diff --git a/lib/src/models.rs b/lib/src/models.rs index 55fef68..6c2372e 100644 --- a/lib/src/models.rs +++ b/lib/src/models.rs @@ -1,5 +1,4 @@ use serde::{Deserialize, Serialize}; -use std::net::SocketAddr; /// User login #[derive(Serialize, Deserialize, Debug)] @@ -21,10 +20,9 @@ pub struct ServerStateSummary { } /// User -#[derive(Clone, Debug, Eq, PartialEq, Hash)] +#[derive(Debug, Eq, PartialEq, Hash)] pub struct User { pub name: String, - pub addr: SocketAddr, } impl User { diff --git a/server/src/api.rs b/server/src/api.rs index 33e18f6..952b23d 100644 --- a/server/src/api.rs +++ b/server/src/api.rs @@ -27,11 +27,12 @@ fn server_sum_update(state: &Arc) -> ServerStateSummary { } } -pub async fn on_websocket_connection(stream: WebSocket, state: Arc, mut who: User) { - // Add user to users - //if doesn't exist - let _true_if_not_exist = &state.users.lock().unwrap().insert(who.clone()); - //etc +pub async fn on_websocket_connection(stream: WebSocket, state: Arc, addr: SocketAddr) { + let new_user = User { + name: "Anonymous".to_string(), + }; + let res = state.users.lock().unwrap().insert(addr.clone(), new_user); + tracing::debug!("{:#?}", res); // By splitting, we can send and receive at the same time. let (mut sender, mut receiver) = stream.split(); @@ -48,7 +49,7 @@ pub async fn on_websocket_connection(stream: WebSocket, state: Arc, mu // ANNOUNCE THY PRESENCE let msg = ChatMessage { - text: format!("{} joined.", who.name), + text: format!("{} joined.", state.users.lock().unwrap().get(&addr).unwrap().name), }; tracing::debug!("{}", msg.text); let _ = &state.tx.send(to_string::(&msg).unwrap()); @@ -73,7 +74,7 @@ pub async fn on_websocket_connection(stream: WebSocket, state: Arc, mu // handle new incoming messages let mut recv_task = tokio::spawn(async move { while let Some(Ok(message)) = receiver.next().await { - message_handler(message, &state, &mut who).await + message_handler(message, &state, addr).await } }); @@ -90,15 +91,6 @@ pub async fn websocket_connection_handler( ConnectInfo(addr): ConnectInfo, State(state): State>, ) -> impl IntoResponse { - tracing::debug!("New connection from {addr}"); - ws.on_upgrade(move |socket| { - on_websocket_connection( - socket, - state, - User { - name: "Anonymous".to_string(), - addr, - }, - ) - }) + tracing::debug!("New connection from {}", &addr); + ws.on_upgrade(move |socket| on_websocket_connection(socket, state, addr)) } diff --git a/server/src/api/message_handler.rs b/server/src/api/message_handler.rs index 2482be3..0228e1e 100644 --- a/server/src/api/message_handler.rs +++ b/server/src/api/message_handler.rs @@ -4,7 +4,7 @@ use crate::api::*; use crate::AppState; use crate::Arc; -pub async fn message_handler(message: Message, state: &Arc, who: &mut User) { +pub async fn message_handler(message: Message, state: &Arc, addr: SocketAddr) { let tx = &state.tx; match message { @@ -27,13 +27,13 @@ pub async fn message_handler(message: Message, state: &Arc, who: &mut let _res = tx.send(String::from("error creating game")); } } else if let Ok(chat_message) = serde_json::from_str::(&text) { - let msg = format! {"{0}: {1}", who.name, chat_message.text}; + let msg = format! {"{0}: {1}", state.users.lock().unwrap().get(&addr).unwrap().name, chat_message.text}; tracing::debug!("{msg}"); let _res = tx.send(to_string::(&ChatMessage { text: msg }).unwrap()); } else if let Ok(user_log_in) = serde_json::from_str::(&text) { - let old_name = who.name.clone(); + let old_name = state.users.lock().unwrap().get(&addr).unwrap().name.clone(); let new_name = user_log_in.username.clone(); - who.change_name(user_log_in.username); + state.users.lock().unwrap().get_mut(&addr).unwrap().change_name(user_log_in.username); let msg = format! { "{0} changed name to {1}.", old_name, @@ -54,7 +54,7 @@ pub async fn message_handler(message: Message, state: &Arc, who: &mut if let Some(cf) = c { tracing::debug!( "Close received from {0} with code: {1} and reason: {2}", - who.addr, + state.users.lock().unwrap().get(&addr).unwrap().name, cf.code, cf.reason ) @@ -62,11 +62,11 @@ pub async fn message_handler(message: Message, state: &Arc, who: &mut tracing::debug!("close received without close frame") } let msg = ChatMessage { - text: format!("{0} left.", who.name), + text: format!("{0} left.", state.users.lock().unwrap().get(&addr).unwrap().name), }; tracing::debug!("{}", msg.text); let _ = tx.send(to_string::(&msg).unwrap()); - let _ = state.users.lock().unwrap().remove(who); + state.users.lock().unwrap().remove(&addr).unwrap(); let _ = tx.send(to_string(&server_sum_update(state)).unwrap()); } diff --git a/server/src/main.rs b/server/src/main.rs index 193b082..c59ff18 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -2,9 +2,8 @@ use anyhow::{Context, Result}; use axum::{response::Html, routing::get, Router}; use axum_extra::response::Css; use lib::models::*; -use std::collections::HashSet; use std::{ - // collections::HashSet, + collections::HashMap, fs, net::SocketAddr, sync::{Arc, Mutex}, @@ -80,7 +79,7 @@ fn test() -> Result<()> { // Our shared state pub struct AppState { // We require unique usernames. This tracks which usernames have been taken. - users: Mutex>, + users: Mutex>, // Channel used to send messages to all connected clients. tx: broadcast::Sender, // Master card decks @@ -118,7 +117,7 @@ async fn main() -> Result<()> { // let user_set = Mutex::new(HashSet::new()); let (tx, _rx) = broadcast::channel(100); // let cards_input_path: &str = "data/cah-cards-full.json"; - let users = Mutex::new(HashSet::::new()); + let users = Mutex::new(HashMap::::new()); // let all_cards = Mutex::new(load_json(cards_input_path)?); let games = Mutex::new(vec![]); let app_state = Arc::new(AppState {