use crate::app::{ClientMessage, ServerMessage}; use crate::whiteboard::Whiteboard; use futures::{FutureExt, SinkExt, StreamExt}; use std::sync::Arc; use tokio::sync::Mutex; use warp::ws::{Message, WebSocket}; pub async fn ws_handler( ws: warp::ws::Ws, whiteboard: Arc>, ) -> Result { Ok(ws.on_upgrade(move |socket| client_connection(socket, whiteboard))) } async fn client_connection(ws: WebSocket, whiteboard: Arc>) { let (mut client_ws_sender, mut client_ws_rcv) = ws.split(); let mut interval = tokio::time::interval(tokio::time::Duration::from_millis(69)); loop { tokio::select! { msg = client_ws_rcv.next().fuse() => { match msg { Some(Ok(msg)) => { if let Ok(text) = msg.to_str() { if let Ok(client_msg) = serde_json::from_str::(text) { let mut wb = whiteboard.lock().await; match client_msg { ClientMessage::Draw(action) => { wb.add_action(action); } ClientMessage::Clear => { wb.clear(); } } } } } _ => break, } } _ = interval.tick() => { let wb = whiteboard.lock().await; let actions = wb.get_actions(); let server_msg = ServerMessage::Update(actions); let msg = serde_json::to_string(&server_msg).unwrap(); if let Err(_) = client_ws_sender.send(Message::text(msg)).await { break; } } } } }