use nanoid instead of UUID

This commit is contained in:
Kay Faraday 2022-05-05 05:40:45 +00:00
parent 61c456eceb
commit 15230facd5
7 changed files with 49 additions and 57 deletions

20
Cargo.lock generated
View File

@ -477,6 +477,15 @@ dependencies = [
"twoway", "twoway",
] ]
[[package]]
name = "nanoid"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ffa00dec017b5b1a8b7cf5e2c008bfda1aa7e0697ac1508b491fdf2622fb4d8"
dependencies = [
"rand 0.8.4",
]
[[package]] [[package]]
name = "ntapi" name = "ntapi"
version = "0.3.6" version = "0.3.6"
@ -1047,15 +1056,6 @@ version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
[[package]]
name = "uuid"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7"
dependencies = [
"getrandom 0.2.3",
]
[[package]] [[package]]
name = "version_check" name = "version_check"
version = "0.9.3" version = "0.9.3"
@ -1119,12 +1119,12 @@ version = "0.1.0"
dependencies = [ dependencies = [
"futures", "futures",
"futures-util", "futures-util",
"nanoid",
"once_cell", "once_cell",
"serde", "serde",
"serde_json", "serde_json",
"tokio", "tokio",
"tokio-stream", "tokio-stream",
"uuid",
"warp", "warp",
] ]

View File

@ -11,5 +11,5 @@ serde = { version = "1.0.130", features = ["derive"] }
serde_json = "1.0.68" serde_json = "1.0.68"
tokio = { version = "1.12.0", features = ["full"] } tokio = { version = "1.12.0", features = ["full"] }
tokio-stream = { version = "0.1.7", features = ["fs"] } tokio-stream = { version = "0.1.7", features = ["fs"] }
uuid = { version = "0.8.2", features = ["v4"] }
warp = "0.3.1" warp = "0.3.1"
nanoid = "0.4.0"

View File

@ -39,7 +39,7 @@
<input <input
type="text" type="text"
id="join-session-id" id="join-session-id"
placeholder="123e4567-e89b-12d3-a456-426614174000" placeholder="zO15dMQnxAUd"
required required
/> />
<button id="join-session-button">Join</button> <button id="join-session-button">Join</button>

View File

@ -69,7 +69,7 @@ export const setupJoinSessionForm = () => {
loadNickname(nickname); loadNickname(nickname);
loadColour(colour); loadColour(colour);
if (window.location.hash.match(/#[0-9a-f\-]+/)) { if (window.location.hash.match(/#[A-Za-z0-9_\-]+/)) {
sessionId.value = window.location.hash.substring(1); sessionId.value = window.location.hash.substring(1);
} }

View File

@ -1,10 +1,11 @@
use serde_json::json; use serde_json::json;
use std::net::IpAddr; use std::net::IpAddr;
use uuid::Uuid;
use warb::{hyper::StatusCode, Filter, Reply}; use warb::{hyper::StatusCode, Filter, Reply};
use warp as warb; // i think it's funny use warp as warb; // i think it's funny
use nanoid::nanoid;
mod events; mod events;
mod utils; mod utils;
mod viewer_connection; mod viewer_connection;
@ -54,39 +55,32 @@ async fn main() {
.and(warb::body::json()) .and(warb::body::json())
.map(|body: StartSessionBody| { .map(|body: StartSessionBody| {
let mut sessions = SESSIONS.lock().unwrap(); let mut sessions = SESSIONS.lock().unwrap();
let session_uuid = Uuid::new_v4(); let session_id = nanoid!(12);
let session = WatchSession::new(body.video_url, body.subtitle_tracks); let session = WatchSession::new(body.video_url, body.subtitle_tracks);
let session_view = session.view(); let session_view = session.view();
sessions.insert(session_uuid, session); sessions.insert(session_id.clone(), session);
warb::reply::json(&json!({ "id": session_uuid.to_string(), "session": session_view })) warb::reply::json(&json!({ "id": session_id.to_string(), "session": session_view }))
}); });
let get_emoji_route = warb::path!("emojos").and_then(get_emoji_list); let get_emoji_route = warb::path!("emojos").and_then(get_emoji_list);
enum RequestedSession { enum RequestedSession {
Session(Uuid, WatchSession), Session(String, WatchSession),
Error(warb::reply::WithStatus<warb::reply::Json>), Error(warb::reply::WithStatus<warb::reply::Json>),
} }
let get_running_session = warb::path::path("sess") let get_running_session = warb::path::path("sess")
.and(warb::path::param::<String>()) .and(warb::path::param::<String>())
.map(|session_id: String| { .map(|session_id: String| {
if let Ok(uuid) = Uuid::parse_str(&session_id) { get_session(&session_id)
get_session(uuid) .map(|sess| RequestedSession::Session(session_id, sess))
.map(|sess| RequestedSession::Session(uuid, sess))
.unwrap_or_else(|| { .unwrap_or_else(|| {
RequestedSession::Error(warb::reply::with_status( RequestedSession::Error(warb::reply::with_status(
warb::reply::json(&json!({ "error": "session does not exist" })), warb::reply::json(&json!({ "error": "session does not exist" })),
StatusCode::NOT_FOUND, StatusCode::NOT_FOUND,
)) ))
}) })
} else {
RequestedSession::Error(warb::reply::with_status(
warb::reply::json(&json!({ "error": "invalid session UUID" })),
StatusCode::BAD_REQUEST,
))
}
}); });
let get_status_route = get_running_session let get_status_route = get_running_session
@ -104,8 +98,8 @@ async fn main() {
.and(warb::ws()) .and(warb::ws())
.map( .map(
|requested_session, query: SubscribeQuery, ws: warb::ws::Ws| match requested_session { |requested_session, query: SubscribeQuery, ws: warb::ws::Ws| match requested_session {
RequestedSession::Session(uuid, _) => ws RequestedSession::Session(session_id, _) => ws
.on_upgrade(move |ws| ws_subscribe(uuid, query.nickname, query.colour, ws)) .on_upgrade(move |ws| ws_subscribe(session_id, query.nickname, query.colour, ws))
.into_response(), .into_response(),
RequestedSession::Error(error_response) => error_response.into_response(), RequestedSession::Error(error_response) => error_response.into_response(),
}, },

View File

@ -11,7 +11,6 @@ use tokio::sync::{
}; };
use tokio_stream::wrappers::UnboundedReceiverStream; use tokio_stream::wrappers::UnboundedReceiverStream;
use uuid::Uuid;
use warp::ws::{Message, WebSocket}; use warp::ws::{Message, WebSocket};
use crate::{ use crate::{
@ -25,14 +24,14 @@ static CONNECTED_VIEWERS: Lazy<RwLock<HashMap<usize, ConnectedViewer>>> =
static NEXT_VIEWER_ID: AtomicUsize = AtomicUsize::new(1); static NEXT_VIEWER_ID: AtomicUsize = AtomicUsize::new(1);
pub struct ConnectedViewer { pub struct ConnectedViewer {
pub session: Uuid, pub session: String,
pub viewer_id: usize, pub viewer_id: usize,
pub tx: UnboundedSender<WatchEvent>, pub tx: UnboundedSender<WatchEvent>,
pub nickname: Option<String>, pub nickname: Option<String>,
pub colour: Option<String>, pub colour: Option<String>,
} }
pub async fn ws_subscribe(session_uuid: Uuid, nickname: String, colour: String, ws: WebSocket) { pub async fn ws_subscribe(session_id: String, nickname: String, colour: String, ws: WebSocket) {
let viewer_id = NEXT_VIEWER_ID.fetch_add(1, Ordering::Relaxed); let viewer_id = NEXT_VIEWER_ID.fetch_add(1, Ordering::Relaxed);
let (mut viewer_ws_tx, mut viewer_ws_rx) = ws.split(); let (mut viewer_ws_tx, mut viewer_ws_rx) = ws.split();
@ -60,7 +59,7 @@ pub async fn ws_subscribe(session_uuid: Uuid, nickname: String, colour: String,
viewer_id, viewer_id,
ConnectedViewer { ConnectedViewer {
viewer_id, viewer_id,
session: session_uuid, session: session_id.to_string(),
tx, tx,
nickname: Some(nickname.clone()), nickname: Some(nickname.clone()),
colour: Some(colour.clone()), colour: Some(colour.clone()),
@ -68,13 +67,13 @@ pub async fn ws_subscribe(session_uuid: Uuid, nickname: String, colour: String,
); );
ws_publish( ws_publish(
session_uuid, &session_id,
None, None,
WatchEvent::new(nickname.clone(), colour.clone(), WatchEventData::UserJoin), WatchEvent::new(nickname.clone(), colour.clone(), WatchEventData::UserJoin),
) )
.await; .await;
update_viewer_list(session_uuid).await; update_viewer_list(&session_id).await;
while let Some(Ok(message)) = viewer_ws_rx.next().await { while let Some(Ok(message)) = viewer_ws_rx.next().await {
let event: WatchEventData = match message let event: WatchEventData = match message
@ -86,7 +85,7 @@ pub async fn ws_subscribe(session_uuid: Uuid, nickname: String, colour: String,
None => continue, None => continue,
}; };
let session = &mut get_session(session_uuid).unwrap(); let session = &mut get_session(&session_id).unwrap();
// server side event modification where neccessary // server side event modification where neccessary
let event: WatchEventData = match event { let event: WatchEventData = match event {
@ -97,10 +96,10 @@ pub async fn ws_subscribe(session_uuid: Uuid, nickname: String, colour: String,
_ => event, _ => event,
}; };
handle_watch_event_data(session_uuid, session, event.clone()); handle_watch_event_data(&session_id, session, event.clone());
ws_publish( ws_publish(
session_uuid, &session_id,
Some(viewer_id), Some(viewer_id),
WatchEvent::new(nickname.clone(), colour.clone(), event), WatchEvent::new(nickname.clone(), colour.clone(), event),
) )
@ -108,19 +107,19 @@ pub async fn ws_subscribe(session_uuid: Uuid, nickname: String, colour: String,
} }
ws_publish( ws_publish(
session_uuid, &session_id,
None, None,
WatchEvent::new(nickname.clone(), colour.clone(), WatchEventData::UserLeave), WatchEvent::new(nickname.clone(), colour.clone(), WatchEventData::UserLeave),
) )
.await; .await;
CONNECTED_VIEWERS.write().await.remove(&viewer_id); CONNECTED_VIEWERS.write().await.remove(&viewer_id);
update_viewer_list(session_uuid).await; update_viewer_list(&session_id).await;
} }
pub async fn ws_publish(session_uuid: Uuid, skip_viewer_id: Option<usize>, event: WatchEvent) { pub async fn ws_publish(session_id: &str, skip_viewer_id: Option<usize>, event: WatchEvent) {
for viewer in CONNECTED_VIEWERS.read().await.values() { for viewer in CONNECTED_VIEWERS.read().await.values() {
if viewer.session != session_uuid { if viewer.session != session_id {
continue; continue;
} }
@ -131,11 +130,11 @@ pub async fn ws_publish(session_uuid: Uuid, skip_viewer_id: Option<usize>, event
} }
} }
async fn update_viewer_list(session_uuid: Uuid) { async fn update_viewer_list(session_id: &str) {
let mut viewers = Vec::new(); let mut viewers = Vec::new();
for viewer in CONNECTED_VIEWERS.read().await.values() { for viewer in CONNECTED_VIEWERS.read().await.values() {
if viewer.session == session_uuid { if viewer.session == session_id {
viewers.push(Viewer { viewers.push(Viewer {
nickname: viewer.nickname.clone(), nickname: viewer.nickname.clone(),
colour: viewer.colour.clone(), colour: viewer.colour.clone(),
@ -144,7 +143,7 @@ async fn update_viewer_list(session_uuid: Uuid) {
} }
ws_publish( ws_publish(
session_uuid, &session_id,
None, None,
WatchEvent::new( WatchEvent::new(
String::from("server"), String::from("server"),

View File

@ -1,7 +1,6 @@
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::{collections::HashMap, sync::Mutex, time::Instant}; use std::{collections::HashMap, sync::Mutex, time::Instant};
use uuid::Uuid;
use crate::events::WatchEventData; use crate::events::WatchEventData;
@ -68,15 +67,15 @@ impl WatchSession {
} }
} }
pub static SESSIONS: Lazy<Mutex<HashMap<Uuid, WatchSession>>> = pub static SESSIONS: Lazy<Mutex<HashMap<String, WatchSession>>> =
Lazy::new(|| Mutex::new(HashMap::new())); Lazy::new(|| Mutex::new(HashMap::new()));
pub fn get_session(uuid: Uuid) -> Option<WatchSession> { pub fn get_session(id: &str) -> Option<WatchSession> {
SESSIONS.lock().unwrap().get(&uuid).cloned() SESSIONS.lock().unwrap().get(id).cloned()
} }
pub fn handle_watch_event_data( pub fn handle_watch_event_data(
uuid: Uuid, id: &str,
watch_session: &mut WatchSession, watch_session: &mut WatchSession,
event: WatchEventData, event: WatchEventData,
) { ) {
@ -92,5 +91,5 @@ pub fn handle_watch_event_data(
_ => {} _ => {}
}; };
let _ = SESSIONS.lock().unwrap().insert(uuid, watch_session.clone()); let _ = SESSIONS.lock().unwrap().insert(id.to_string(), watch_session.clone());
} }