fix duplicating users

This commit is contained in:
Adam 2024-07-27 02:51:04 -04:00
parent cafac264a7
commit 22af4d94d6
4 changed files with 21 additions and 32 deletions

View file

@ -1,5 +1,4 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::net::SocketAddr;
/// User login /// User login
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
@ -21,10 +20,9 @@ pub struct ServerStateSummary {
} }
/// User /// User
#[derive(Clone, Debug, Eq, PartialEq, Hash)] #[derive(Debug, Eq, PartialEq, Hash)]
pub struct User { pub struct User {
pub name: String, pub name: String,
pub addr: SocketAddr,
} }
impl User { impl User {

View file

@ -27,11 +27,12 @@ fn server_sum_update(state: &Arc<AppState>) -> ServerStateSummary {
} }
} }
pub async fn on_websocket_connection(stream: WebSocket, state: Arc<AppState>, mut who: User) { pub async fn on_websocket_connection(stream: WebSocket, state: Arc<AppState>, addr: SocketAddr) {
// Add user to users let new_user = User {
//if doesn't exist name: "Anonymous".to_string(),
let _true_if_not_exist = &state.users.lock().unwrap().insert(who.clone()); };
//etc 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. // By splitting, we can send and receive at the same time.
let (mut sender, mut receiver) = stream.split(); let (mut sender, mut receiver) = stream.split();
@ -48,7 +49,7 @@ pub async fn on_websocket_connection(stream: WebSocket, state: Arc<AppState>, mu
// ANNOUNCE THY PRESENCE // ANNOUNCE THY PRESENCE
let msg = ChatMessage { let msg = ChatMessage {
text: format!("{} joined.", who.name), text: format!("{} joined.", state.users.lock().unwrap().get(&addr).unwrap().name),
}; };
tracing::debug!("{}", msg.text); tracing::debug!("{}", msg.text);
let _ = &state.tx.send(to_string::<ChatMessage>(&msg).unwrap()); let _ = &state.tx.send(to_string::<ChatMessage>(&msg).unwrap());
@ -73,7 +74,7 @@ pub async fn on_websocket_connection(stream: WebSocket, state: Arc<AppState>, mu
// handle new incoming messages // handle new incoming messages
let mut recv_task = tokio::spawn(async move { let mut recv_task = tokio::spawn(async move {
while let Some(Ok(message)) = receiver.next().await { 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<SocketAddr>, ConnectInfo(addr): ConnectInfo<SocketAddr>,
State(state): State<Arc<AppState>>, State(state): State<Arc<AppState>>,
) -> impl IntoResponse { ) -> impl IntoResponse {
tracing::debug!("New connection from {addr}"); tracing::debug!("New connection from {}", &addr);
ws.on_upgrade(move |socket| { ws.on_upgrade(move |socket| on_websocket_connection(socket, state, addr))
on_websocket_connection(
socket,
state,
User {
name: "Anonymous".to_string(),
addr,
},
)
})
} }

View file

@ -4,7 +4,7 @@ use crate::api::*;
use crate::AppState; use crate::AppState;
use crate::Arc; use crate::Arc;
pub async fn message_handler(message: Message, state: &Arc<AppState>, who: &mut User) { pub async fn message_handler(message: Message, state: &Arc<AppState>, addr: SocketAddr) {
let tx = &state.tx; let tx = &state.tx;
match message { match message {
@ -27,13 +27,13 @@ pub async fn message_handler(message: Message, state: &Arc<AppState>, who: &mut
let _res = tx.send(String::from("error creating game")); let _res = tx.send(String::from("error creating game"));
} }
} else if let Ok(chat_message) = serde_json::from_str::<ChatMessage>(&text) { } else if let Ok(chat_message) = serde_json::from_str::<ChatMessage>(&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}"); tracing::debug!("{msg}");
let _res = tx.send(to_string::<ChatMessage>(&ChatMessage { text: msg }).unwrap()); let _res = tx.send(to_string::<ChatMessage>(&ChatMessage { text: msg }).unwrap());
} else if let Ok(user_log_in) = serde_json::from_str::<UserLogIn>(&text) { } else if let Ok(user_log_in) = serde_json::from_str::<UserLogIn>(&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(); 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! { let msg = format! {
"{0} changed name to {1}.", "{0} changed name to {1}.",
old_name, old_name,
@ -54,7 +54,7 @@ pub async fn message_handler(message: Message, state: &Arc<AppState>, who: &mut
if let Some(cf) = c { if let Some(cf) = c {
tracing::debug!( tracing::debug!(
"Close received from {0} with code: {1} and reason: {2}", "Close received from {0} with code: {1} and reason: {2}",
who.addr, state.users.lock().unwrap().get(&addr).unwrap().name,
cf.code, cf.code,
cf.reason cf.reason
) )
@ -62,11 +62,11 @@ pub async fn message_handler(message: Message, state: &Arc<AppState>, who: &mut
tracing::debug!("close received without close frame") tracing::debug!("close received without close frame")
} }
let msg = ChatMessage { 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); tracing::debug!("{}", msg.text);
let _ = tx.send(to_string::<ChatMessage>(&msg).unwrap()); let _ = tx.send(to_string::<ChatMessage>(&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()); let _ = tx.send(to_string(&server_sum_update(state)).unwrap());
} }

View file

@ -2,9 +2,8 @@ use anyhow::{Context, Result};
use axum::{response::Html, routing::get, Router}; use axum::{response::Html, routing::get, Router};
use axum_extra::response::Css; use axum_extra::response::Css;
use lib::models::*; use lib::models::*;
use std::collections::HashSet;
use std::{ use std::{
// collections::HashSet, collections::HashMap,
fs, fs,
net::SocketAddr, net::SocketAddr,
sync::{Arc, Mutex}, sync::{Arc, Mutex},
@ -80,7 +79,7 @@ fn test() -> Result<()> {
// Our shared state // Our shared state
pub struct AppState { pub struct AppState {
// We require unique usernames. This tracks which usernames have been taken. // We require unique usernames. This tracks which usernames have been taken.
users: Mutex<HashSet<User>>, users: Mutex<HashMap<SocketAddr, User>>,
// Channel used to send messages to all connected clients. // Channel used to send messages to all connected clients.
tx: broadcast::Sender<String>, tx: broadcast::Sender<String>,
// Master card decks // Master card decks
@ -118,7 +117,7 @@ async fn main() -> Result<()> {
// let user_set = Mutex::new(HashSet::new()); // let user_set = Mutex::new(HashSet::new());
let (tx, _rx) = broadcast::channel(100); let (tx, _rx) = broadcast::channel(100);
// let cards_input_path: &str = "data/cah-cards-full.json"; // let cards_input_path: &str = "data/cah-cards-full.json";
let users = Mutex::new(HashSet::<User>::new()); let users = Mutex::new(HashMap::<SocketAddr, User>::new());
// let all_cards = Mutex::new(load_json(cards_input_path)?); // let all_cards = Mutex::new(load_json(cards_input_path)?);
let games = Mutex::new(vec![]); let games = Mutex::new(vec![]);
let app_state = Arc::new(AppState { let app_state = Arc::new(AppState {