| 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<Mutex<Whiteboard>>, | |
| ) -> Result<impl warp::Reply, warp::Rejection> { | |
| Ok(ws.on_upgrade(move |socket| client_connection(socket, whiteboard))) | |
| } | |
| async fn client_connection(ws: WebSocket, whiteboard: Arc<Mutex<Whiteboard>>) { | |
| 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::<ClientMessage>(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; | |
| } | |
| } | |
| } | |
| } | |
| } | |