message handler
This commit is contained in:
parent
4fa78181c7
commit
33d81fd316
3 changed files with 71 additions and 63 deletions
55
src/api.rs
55
src/api.rs
|
@ -1,16 +1,17 @@
|
|||
use crate::gamemaster::*;
|
||||
use crate::AppState;
|
||||
use axum::extract::ConnectInfo;
|
||||
use axum::{
|
||||
extract::{
|
||||
ws::{Message, WebSocket, WebSocketUpgrade},
|
||||
State,
|
||||
ConnectInfo, State,
|
||||
},
|
||||
response::IntoResponse,
|
||||
};
|
||||
use futures::{sink::SinkExt, stream::StreamExt};
|
||||
use serde::Deserialize;
|
||||
use std::{net::SocketAddr, sync::Arc};
|
||||
pub mod message_handler;
|
||||
use crate::message_handler::*;
|
||||
|
||||
/// New game request structure
|
||||
#[derive(Debug, Deserialize)]
|
||||
|
@ -51,6 +52,7 @@ fn greeting(state: &Arc<AppState>) -> String {
|
|||
state.games.lock().unwrap().len(),
|
||||
)
|
||||
}
|
||||
|
||||
pub async fn websocket(stream: WebSocket, state: Arc<AppState>, who: SocketAddr) {
|
||||
// By splitting, we can send and receive at the same time.
|
||||
let (mut sender, mut receiver) = stream.split();
|
||||
|
@ -74,57 +76,10 @@ pub async fn websocket(stream: WebSocket, state: Arc<AppState>, who: SocketAddr)
|
|||
}
|
||||
});
|
||||
|
||||
// clone things for receiving task
|
||||
let tx = state.tx.clone();
|
||||
let name = who.clone();
|
||||
|
||||
// handle new incoming messages
|
||||
let mut recv_task = tokio::spawn(async move {
|
||||
while let Some(Ok(message)) = receiver.next().await {
|
||||
match message {
|
||||
Message::Text(text) => {
|
||||
tracing::debug!("{who}: {}", text);
|
||||
|
||||
if let Ok(new_game) = serde_json::from_str::<NewGameRequest>(&text) {
|
||||
tracing::debug!("{:#?}", &new_game);
|
||||
// create game
|
||||
if let Ok(new_game_object) = CAHGame::new(new_game) {
|
||||
state.games.lock().unwrap().push(new_game_object);
|
||||
let _update = tx.send(greeting(&state));
|
||||
} else {
|
||||
let _res = tx.send(format!("error creating game"));
|
||||
}
|
||||
} else {
|
||||
// just echo
|
||||
let msg = format!{"{who}: {text}"};
|
||||
tracing::debug!("{msg}");
|
||||
let _res = tx.send(msg);
|
||||
}
|
||||
}
|
||||
Message::Binary(data) => {
|
||||
tracing::debug!("Binary: {:?}", data)
|
||||
}
|
||||
Message::Close(c) => {
|
||||
if let Some(cf) = c {
|
||||
tracing::debug!(
|
||||
"Close received from {who} with code: {} and reason: {}",
|
||||
cf.code,
|
||||
cf.reason
|
||||
)
|
||||
} else {
|
||||
tracing::debug!("close received without close frame")
|
||||
}
|
||||
let msg = format!("{name} left.");
|
||||
tracing::debug!("{msg}");
|
||||
let _ = tx.send(msg);
|
||||
}
|
||||
Message::Pong(ping) => {
|
||||
tracing::debug!("Pong received with: {:?}", ping);
|
||||
}
|
||||
Message::Ping(pong) => {
|
||||
tracing::debug!("Pong received with: {:?}", pong);
|
||||
}
|
||||
}
|
||||
message_handler(message, &state, who).await
|
||||
}
|
||||
});
|
||||
|
||||
|
|
58
src/api/message_handler.rs
Normal file
58
src/api/message_handler.rs
Normal file
|
@ -0,0 +1,58 @@
|
|||
use crate::api::{greeting, Message, SocketAddr};
|
||||
use crate::AppState;
|
||||
use crate::Arc;
|
||||
use crate::CAHGame;
|
||||
use crate::NewGameRequest;
|
||||
|
||||
pub async fn message_handler(message: Message, state: &Arc<AppState>, who: SocketAddr) {
|
||||
let tx = &state.tx;
|
||||
|
||||
match message {
|
||||
Message::Text(text) => {
|
||||
tracing::debug!("{who}: {}", text);
|
||||
|
||||
if let Ok(new_game) = serde_json::from_str::<NewGameRequest>(&text) {
|
||||
tracing::debug!("{:#?}", &new_game);
|
||||
// create game
|
||||
if let Ok(new_game_object) = CAHGame::new(new_game) {
|
||||
state.games.lock().unwrap().push(new_game_object);
|
||||
let _update = tx.send(greeting(&state));
|
||||
} else {
|
||||
let _res = tx.send(format!("error creating game"));
|
||||
}
|
||||
} else {
|
||||
// just echo
|
||||
let msg = format! {"{who}: {text}"};
|
||||
tracing::debug!("{msg}");
|
||||
let _res = tx.send(msg);
|
||||
}
|
||||
}
|
||||
|
||||
Message::Binary(data) => {
|
||||
tracing::debug!("Binary: {:?}", data)
|
||||
}
|
||||
|
||||
Message::Close(c) => {
|
||||
if let Some(cf) = c {
|
||||
tracing::debug!(
|
||||
"Close received from {who} with code: {} and reason: {}",
|
||||
cf.code,
|
||||
cf.reason
|
||||
)
|
||||
} else {
|
||||
tracing::debug!("close received without close frame")
|
||||
}
|
||||
let msg = format!("{who} left.");
|
||||
tracing::debug!("{msg}");
|
||||
let _ = tx.send(msg);
|
||||
}
|
||||
|
||||
Message::Pong(ping) => {
|
||||
tracing::debug!("Pong received with: {:?}", ping);
|
||||
}
|
||||
|
||||
Message::Ping(pong) => {
|
||||
tracing::debug!("Pong received with: {:?}", pong);
|
||||
}
|
||||
}
|
||||
}
|
21
src/main.rs
21
src/main.rs
|
@ -1,16 +1,16 @@
|
|||
use axum::{response::Html, routing::get, Router, ServiceExt};
|
||||
use axum::{response::Html, routing::get, Router};
|
||||
use std::{
|
||||
collections::HashSet,
|
||||
// collections::HashSet,
|
||||
error::Error,
|
||||
fs,
|
||||
net::SocketAddr,
|
||||
result::Result,
|
||||
sync::{Arc, Mutex},
|
||||
};
|
||||
use std::{error::Error, fs, result::Result};
|
||||
use tokio::sync::broadcast;
|
||||
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
|
||||
|
||||
pub mod gamemaster;
|
||||
use crate::gamemaster::*;
|
||||
|
||||
pub mod api;
|
||||
use crate::api::*;
|
||||
|
||||
|
@ -76,7 +76,7 @@ fn test() -> Result<(), Box<dyn Error>> {
|
|||
// Our shared state
|
||||
pub struct AppState {
|
||||
// We require unique usernames. This tracks which usernames have been taken.
|
||||
user_set: Mutex<HashSet<String>>,
|
||||
// user_set: Mutex<HashSet<String>>,
|
||||
// Channel used to send messages to all connected clients.
|
||||
tx: broadcast::Sender<String>,
|
||||
// Master card decks
|
||||
|
@ -96,18 +96,13 @@ async fn main() -> Result<(), Box<dyn Error>> {
|
|||
.init();
|
||||
|
||||
// Set up application state for use with with_state().
|
||||
let user_set = Mutex::new(HashSet::new());
|
||||
// let user_set = Mutex::new(HashSet::new());
|
||||
let (tx, _rx) = broadcast::channel(100);
|
||||
|
||||
// choose decks
|
||||
let cards_input_path: &str = "data/cah-cards-full.json";
|
||||
|
||||
// TODO: this should be a master card database and pointers
|
||||
// to the cards should be passed to the game instead of actual cards
|
||||
let all_cards = Mutex::new(load_json(cards_input_path)?);
|
||||
let games = Mutex::new(vec![]);
|
||||
let app_state = Arc::new(AppState {
|
||||
user_set,
|
||||
// user_set,
|
||||
tx,
|
||||
all_cards,
|
||||
games,
|
||||
|
|
Loading…
Add table
Reference in a new issue