use nanoid instead of UUID
This commit is contained in:
parent
61c456eceb
commit
15230facd5
|
@ -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",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -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"
|
|
@ -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>
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
38
src/main.rs
38
src/main.rs
|
@ -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(),
|
||||||
},
|
},
|
||||||
|
|
|
@ -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"),
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue