diff --git a/Server/src/network_service.rs b/Server/src/network_service.rs index 3bcaf27..c0265bb 100644 --- a/Server/src/network_service.rs +++ b/Server/src/network_service.rs @@ -1,3 +1,4 @@ +mod message_dispatcher; mod tcp_server; use tcp_server::TcpServer; diff --git a/Server/src/network_service/message_dispatcher.rs b/Server/src/network_service/message_dispatcher.rs new file mode 100644 index 0000000..393d171 --- /dev/null +++ b/Server/src/network_service/message_dispatcher.rs @@ -0,0 +1,68 @@ +use std::collections::HashMap; +use std::sync::LazyLock; + +use tokio::sync::RwLock; + +pub(crate) struct MessageDispatcher +where + H: Fn(String) + Send + Sync, +{ + handlers: RwLock>, +} + +pub(crate) static DISPATCHER: LazyLock>> = + LazyLock::new(MessageDispatcher::new); + +impl MessageDispatcher +where + H: Fn(String) + Send + Sync, +{ + fn new() -> Self { + Self { + handlers: RwLock::new(HashMap::new()), + } + } + + pub(crate) async fn register_handler(&self, handler_name: String, handler: H) { + let mut handlers = self.handlers.write().await; + handlers.insert(handler_name, handler); + } + + pub(crate) async fn dispatch(&self, handler_name: String, message: String) { + let handlers = self.handlers.read().await; + + match handlers.get(&handler_name) { + Some(handler) => handler(message), + None => log::error!( + "The handler corresponds to this kind of message hasn't been registered!" + ), + } + } +} + +mod test { + #[tokio::test] + async fn test_dispatch() { + use super::DISPATCHER; + + DISPATCHER + .register_handler( + "UserLogin".into(), + Box::new(|message| println!("Received message: {message}")), + ) + .await; + DISPATCHER + .register_handler( + "UserSignUp".into(), + Box::new(|message| println!("Received message: {message}")), + ) + .await; + + DISPATCHER + .dispatch("UserLogin".into(), "I want to login".into()) + .await; + DISPATCHER + .dispatch("UserSignUp".into(), "I want to signup".into()) + .await; + } +}