diff options
Diffstat (limited to 'src/rooms.rs')
-rw-r--r-- | src/rooms.rs | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/src/rooms.rs b/src/rooms.rs new file mode 100644 index 0000000..c8199d1 --- /dev/null +++ b/src/rooms.rs @@ -0,0 +1,59 @@ +use std::collections::HashMap; + +use axum::extract::ws::WebSocket; +use tokio::sync::mpsc; +use tokio::sync::oneshot; + +use super::room; + +pub enum RoomServiceRequest { + Exists(String, oneshot::Sender<bool>), + Join(String, WebSocket), + Remove(String), +} + +pub type RoomService = mpsc::Sender<RoomServiceRequest>; + +type RoomMap = HashMap<String, room::Room>; + +async fn handle_room_server_message(rooms: &mut RoomMap, req: RoomServiceRequest, tx: RoomService) { + match req { + // check whether a given room exists + // the sender must provide a tokio::sync::oneshot sender to receive a response + RoomServiceRequest::Exists(code, reply) => { + reply.send(rooms.get(&code).is_some()).ok(); + }, + // send a websocket into the given room, starting it if it doesn't exist + RoomServiceRequest::Join(code, ws) => { + let room = match rooms.get(&code) { + Some(rm) => rm, + None => { + let rm = room::start_room(code.clone(), tx); + rooms.insert(code.clone(), rm); + &rooms[&code] + } + }; + + room::add_connection(room, ws).await; + }, + // remove a room (called by the room task itself once there are no more connections to it) + RoomServiceRequest::Remove(code) => { + rooms.remove(&code); + } + } +} + +// a task to manage a hashmap holding the room task senders +// returns a sender to interface with the task +pub fn start_room_server() -> RoomService { + let (tx, mut rx) = mpsc::channel::<RoomServiceRequest>(10); + let txret = tx.clone(); + + tokio::spawn(async move { + let mut rooms: RoomMap = HashMap::new(); + while let Some(req) = rx.recv().await { + handle_room_server_message(&mut rooms, req, tx.clone()).await; + } + }); + txret +} |