let user handler handle user things
This commit is contained in:
parent
a95deceef9
commit
3fb3d2f521
6 changed files with 110 additions and 107 deletions
|
@ -7,11 +7,12 @@ use thaw::*;
|
|||
#[component]
|
||||
pub fn Debug() -> impl IntoView {
|
||||
let websocket = expect_context::<WebSocketContext>();
|
||||
let state_summary = expect_context::<ReadSignal<Option<ServerStateSummary>>>();
|
||||
let server_online_users = expect_context::<ReadSignal<Option<ServerOnlineUsers>>>();
|
||||
let server_active_games = expect_context::<ReadSignal<Option<ServerActiveGames>>>();
|
||||
|
||||
// Signals
|
||||
let (online_users, set_online_users) = signal(0);
|
||||
let (active_games, set_active_games) = signal(0);
|
||||
let user_count = RwSignal::new(0);
|
||||
let game_count = RwSignal::new(0);
|
||||
|
||||
// Websocket stuff
|
||||
let status = move || websocket.ready_state.get().to_string();
|
||||
|
@ -27,17 +28,24 @@ pub fn Debug() -> impl IntoView {
|
|||
|
||||
let close_connection = move |_| {
|
||||
(websocket.close)();
|
||||
set_online_users(0);
|
||||
set_active_games(0);
|
||||
user_count.set(0);
|
||||
game_count.set(0);
|
||||
};
|
||||
|
||||
// Update server info -> move this to a new component
|
||||
// Update data on incoming updates
|
||||
Effect::new(move |_| {
|
||||
state_summary.with(move |state_summary| {
|
||||
if let Some(state_summary) = state_summary {
|
||||
set_online_users(state_summary.online_users);
|
||||
set_active_games(state_summary.active_games);
|
||||
}
|
||||
server_online_users.with(move |server_online_users| {
|
||||
if let Some(online_users) = server_online_users {
|
||||
user_count.set(online_users.online_users);
|
||||
};
|
||||
})
|
||||
});
|
||||
|
||||
Effect::new(move |_| {
|
||||
server_active_games.with(move |server_active_games| {
|
||||
if let Some(active_games) = server_active_games {
|
||||
game_count.set(active_games.active_games);
|
||||
};
|
||||
})
|
||||
});
|
||||
|
||||
|
@ -45,8 +53,8 @@ pub fn Debug() -> impl IntoView {
|
|||
<div class="my-2 w-auto">
|
||||
<h2 class="p-1 text-2xl">Debug:</h2>
|
||||
<p class="p-1">"Connection Status: " {status}</p>
|
||||
<p class="p-1">"Users Online: " {online_users}</p>
|
||||
<p class="p-1">"Active Games: " {active_games}</p>
|
||||
<p class="p-1">"Users Online: " {user_count}</p>
|
||||
<p class="p-1">"Active Games: " {game_count}</p>
|
||||
<div class="p-1">
|
||||
<Button on_click=open_connection disabled=connected>
|
||||
"Connect"
|
||||
|
|
|
@ -68,7 +68,8 @@ pub fn Websocket() -> impl IntoView {
|
|||
|
||||
// Contexts for message handler
|
||||
// TODO: This context stuff can probably be done better
|
||||
let (state_summary, set_state_summary) = signal::<Option<ServerStateSummary>>(Option::None);
|
||||
let (users_count, set_users_count) = signal::<Option<ServerOnlineUsers>>(Option::None);
|
||||
let (games_count, set_games_count) = signal::<Option<ServerActiveGames>>(Option::None);
|
||||
let (active_games, set_active_games) = signal::<Vec<GameBrowserMeta>>(vec![]);
|
||||
let (user_update, set_user_update) = signal::<Option<UserUpdate>>(Option::None);
|
||||
let (chat_update, set_chat_update) = signal::<Option<ChatUpdate>>(Option::None);
|
||||
|
@ -102,14 +103,17 @@ pub fn Websocket() -> impl IntoView {
|
|||
provide_context::<ReadSignal<Vec<GameBrowserMeta>>>(active_games);
|
||||
provide_context::<ReadSignal<Option<GameMeta>>>(game_meta);
|
||||
provide_context::<ReadSignal<Option<GameStateMeta>>>(game_state);
|
||||
provide_context::<ReadSignal<Option<ServerStateSummary>>>(state_summary);
|
||||
provide_context::<ReadSignal<Option<ServerOnlineUsers>>>(users_count);
|
||||
provide_context::<ReadSignal<Option<ServerActiveGames>>>(games_count);
|
||||
|
||||
// Message handler
|
||||
Effect::new(move |_| {
|
||||
message.with(move |message_raw| {
|
||||
if let Some(message) = message_raw {
|
||||
if let Ok(state_summary) = from_str::<ServerStateSummary>(message) {
|
||||
set_state_summary(Some(state_summary));
|
||||
if let Ok(users_count) = from_str::<ServerOnlineUsers>(message) {
|
||||
set_users_count(Some(users_count));
|
||||
} else if let Ok(games_count) = from_str::<ServerActiveGames>(message) {
|
||||
set_games_count(Some(games_count));
|
||||
} else if let Ok(chat_message) = from_str::<ChatMessage>(message) {
|
||||
set_chat_message(Some(chat_message));
|
||||
} else if let Ok(user_update) = from_str::<UserUpdate>(message) {
|
||||
|
|
|
@ -126,10 +126,15 @@ pub struct ChatMessage {
|
|||
pub text: String,
|
||||
}
|
||||
|
||||
/// Server state summary
|
||||
/// Server user count
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct ServerStateSummary {
|
||||
pub struct ServerOnlineUsers {
|
||||
pub online_users: usize,
|
||||
}
|
||||
|
||||
/// Server games count
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct ServerActiveGames {
|
||||
pub active_games: usize,
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
use crate::game::*;
|
||||
use crate::user_handler::*;
|
||||
use crate::AppState;
|
||||
use crate::DmUserMethod::*;
|
||||
use crate::GameHandlerMessage::*;
|
||||
|
@ -202,17 +201,8 @@ impl GameHandler {
|
|||
// Send updates for all players
|
||||
self.send_game_meta_update(vec![game_id.clone()]);
|
||||
|
||||
// Update games list
|
||||
self.broadcast_game_browser_update();
|
||||
|
||||
// Broadcast server meta update
|
||||
if let Err(e) = self
|
||||
.state
|
||||
.broadcast_tx
|
||||
.send(meta_server_summary_update(&self.state))
|
||||
{
|
||||
tracing::error!("Could not broadcast server meta update: {}", e);
|
||||
};
|
||||
self.broadcast_game_count();
|
||||
}
|
||||
|
||||
/// Send game meta update for all players of a game
|
||||
|
@ -384,17 +374,8 @@ impl GameHandler {
|
|||
self.send_game_state_update_all(vec![game_id.clone()]);
|
||||
self.send_game_meta_update(vec![game_id]);
|
||||
|
||||
// Update games list
|
||||
self.broadcast_game_browser_update();
|
||||
|
||||
// Broadcast server meta update
|
||||
let msg = meta_server_summary_update(&self.state);
|
||||
let tx = self.state.broadcast_tx.clone();
|
||||
tokio::spawn(async move {
|
||||
if let Err(e) = tx.send(msg) {
|
||||
tracing::error!("Could not broadcast server meta update: {}", e);
|
||||
}
|
||||
});
|
||||
self.broadcast_game_count();
|
||||
} else {
|
||||
tracing::error!("Attempted to create game for nonexistent player!");
|
||||
}
|
||||
|
@ -427,4 +408,12 @@ impl GameHandler {
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
/// Broadcast updated game count
|
||||
fn broadcast_game_count(&self) {
|
||||
let tx = self.state.broadcast_tx.clone();
|
||||
let active_games = self.state.games.read().unwrap().len();
|
||||
let msg = to_string(&ServerActiveGames { active_games }).unwrap();
|
||||
tokio::spawn(async move { tx.send(msg) });
|
||||
}
|
||||
}
|
||||
|
|
|
@ -151,68 +151,19 @@ impl MessageHandler {
|
|||
/// This runs when a connection closes
|
||||
fn handle_close(&self, close_frame: Option<CloseFrame>, addr: SocketAddr) {
|
||||
// TODO: this is user handler's job
|
||||
let user_name = self
|
||||
.state
|
||||
.online_users
|
||||
.read()
|
||||
.unwrap()
|
||||
.get(&addr)
|
||||
.unwrap()
|
||||
.read()
|
||||
.unwrap()
|
||||
.name
|
||||
.clone();
|
||||
|
||||
// Announce User left in chat
|
||||
let msg = ChatMessage {
|
||||
text: format!("{0} left.", &user_name),
|
||||
};
|
||||
let chat_message = to_string::<ChatMessage>(&msg).unwrap();
|
||||
let tx = self.state.broadcast_tx.clone();
|
||||
tokio::spawn(async move {
|
||||
if let Err(e) = tx.send(chat_message) {
|
||||
tracing::error!("Error broadcasting user leave message: {}", e)
|
||||
}
|
||||
});
|
||||
let msg = UserHandlerMessage::Cleanup(addr);
|
||||
let tx = self.state.users_tx.clone();
|
||||
tokio::spawn(async move { tx.send(msg).await });
|
||||
|
||||
// Process close frame
|
||||
if let Some(cf) = close_frame {
|
||||
tracing::info!(
|
||||
"Close received from {0} with code: {1} and reason: {2}",
|
||||
&user_name,
|
||||
"Close received with code: {} and reason: {}",
|
||||
cf.code,
|
||||
cf.reason
|
||||
)
|
||||
} else {
|
||||
tracing::info!("close received without close frame")
|
||||
}
|
||||
|
||||
// Move user to offline
|
||||
// TODO: This is user handler's job
|
||||
self.state.offline_users.write().unwrap().insert(
|
||||
user_name,
|
||||
self.state
|
||||
.online_users
|
||||
.write()
|
||||
.unwrap()
|
||||
.remove(&addr)
|
||||
.unwrap(),
|
||||
);
|
||||
|
||||
// Send client updates
|
||||
let msg = meta_server_summary_update(&self.state);
|
||||
let tx = self.state.broadcast_tx.clone();
|
||||
tokio::spawn(async move {
|
||||
if let Err(e) = tx.send(msg) {
|
||||
tracing::error!("Error broadcasting server summary update: {}", e)
|
||||
}
|
||||
});
|
||||
let msg = meta_chat_update(&self.state);
|
||||
let tx = self.state.broadcast_tx.clone();
|
||||
tokio::spawn(async move {
|
||||
if let Err(e) = tx.send(msg) {
|
||||
tracing::error!("Error broadcasting chat update: {}", e)
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ pub enum UserHandlerMessage {
|
|||
NewUser(User, SocketAddr),
|
||||
UserLogIn(UserLogInRequest, SocketAddr),
|
||||
DmUser(SendUserMessage, DmUserMethod),
|
||||
Cleanup(SocketAddr),
|
||||
}
|
||||
|
||||
/// Types of messages that can be sent to a user as a DM
|
||||
|
@ -51,6 +52,7 @@ impl UserHandler {
|
|||
}
|
||||
UserLogIn(request, addr) => self.login(request, addr).await,
|
||||
DmUser(message, method) => self.dm_user(message, method).await,
|
||||
Cleanup(addr) => self.user_cleanup(addr),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -148,9 +150,8 @@ impl UserHandler {
|
|||
let msg = meta_announce_user_join(&self.state, &addr);
|
||||
tokio::spawn(async move { tx.send(msg) });
|
||||
|
||||
let tx = self.state.broadcast_tx.clone();
|
||||
let msg = meta_server_summary_update(&self.state);
|
||||
tokio::spawn(async move { tx.send(msg) });
|
||||
self.broadcast_user_count();
|
||||
|
||||
let tx = self.state.broadcast_tx.clone();
|
||||
let msg = meta_chat_update(&self.state);
|
||||
tokio::spawn(async move { tx.send(msg) });
|
||||
|
@ -310,6 +311,62 @@ impl UserHandler {
|
|||
let msg = meta_chat_update(&self.state);
|
||||
tokio::spawn(async move { tx.send(msg) });
|
||||
}
|
||||
|
||||
/// Broadcast updated user count
|
||||
fn broadcast_user_count(&self) {
|
||||
let tx = self.state.broadcast_tx.clone();
|
||||
let online_users = self.state.online_users.read().unwrap().len();
|
||||
let msg = to_string(&ServerOnlineUsers { online_users }).unwrap();
|
||||
tokio::spawn(async move { tx.send(msg) });
|
||||
}
|
||||
|
||||
/// Clean up after a user when they disconnect
|
||||
fn user_cleanup(&self, addr: SocketAddr) {
|
||||
let user_name = self
|
||||
.state
|
||||
.online_users
|
||||
.read()
|
||||
.unwrap()
|
||||
.get(&addr)
|
||||
.unwrap()
|
||||
.read()
|
||||
.unwrap()
|
||||
.name
|
||||
.clone();
|
||||
|
||||
// Announce User left in chat
|
||||
let msg = ChatMessage {
|
||||
text: format!("{0} left.", &user_name),
|
||||
};
|
||||
let chat_message = to_string::<ChatMessage>(&msg).unwrap();
|
||||
let tx = self.state.broadcast_tx.clone();
|
||||
tokio::spawn(async move {
|
||||
if let Err(e) = tx.send(chat_message) {
|
||||
tracing::error!("Error broadcasting user leave message: {}", e)
|
||||
}
|
||||
});
|
||||
|
||||
// Move user to offline
|
||||
self.state.offline_users.write().unwrap().insert(
|
||||
user_name,
|
||||
self.state
|
||||
.online_users
|
||||
.write()
|
||||
.unwrap()
|
||||
.remove(&addr)
|
||||
.unwrap(),
|
||||
);
|
||||
|
||||
self.broadcast_user_count();
|
||||
|
||||
let msg = meta_chat_update(&self.state);
|
||||
let tx = self.state.broadcast_tx.clone();
|
||||
tokio::spawn(async move {
|
||||
if let Err(e) = tx.send(msg) {
|
||||
tracing::error!("Error broadcasting chat update: {}", e)
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// Generate message to notify client of user changes
|
||||
|
@ -361,14 +418,3 @@ pub fn meta_motd() -> String {
|
|||
})
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
/// Generate server summary update - mostly debug stuff
|
||||
pub fn meta_server_summary_update(state: &Arc<AppState>) -> String {
|
||||
let online_users = state.online_users.read().unwrap().len();
|
||||
let active_games = state.games.read().unwrap().len();
|
||||
to_string::<ServerStateSummary>(&ServerStateSummary {
|
||||
online_users,
|
||||
active_games,
|
||||
})
|
||||
.unwrap()
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue