From 8f3cbc65d0686aea2f1ce6f5db2214dc7c4f48ff Mon Sep 17 00:00:00 2001 From: Win Date: Fri, 21 Feb 2025 23:51:48 +0700 Subject: [PATCH] updated the HCD-201 essay --- ...Code of Ethics - Thanawin Pattanaphol.odt# | 1 + ... Code of Ethics - Thanawin Pattanaphol.odt | Bin 0 -> 41666 bytes .../00010/rust-chat-server/server/Cargo.toml | 40 +++++++++--------- .../server/src/room_manager/mod.rs | 11 ++++- .../server/src/room_manager/room/chat_room.rs | 32 +++++++++++--- .../room_manager/room/user_session_handle.rs | 3 -- 6 files changed, 56 insertions(+), 31 deletions(-) create mode 100644 spring-2025/hcd-201/.~lock.HCD-201:00010 - Understanding and Applying ACM Code of Ethics - Thanawin Pattanaphol.odt# create mode 100644 spring-2025/hcd-201/HCD-201:00010 - Understanding and Applying ACM Code of Ethics - Thanawin Pattanaphol.odt diff --git a/spring-2025/hcd-201/.~lock.HCD-201:00010 - Understanding and Applying ACM Code of Ethics - Thanawin Pattanaphol.odt# b/spring-2025/hcd-201/.~lock.HCD-201:00010 - Understanding and Applying ACM Code of Ethics - Thanawin Pattanaphol.odt# new file mode 100644 index 0000000..a0df39b --- /dev/null +++ b/spring-2025/hcd-201/.~lock.HCD-201:00010 - Understanding and Applying ACM Code of Ethics - Thanawin Pattanaphol.odt# @@ -0,0 +1 @@ +,winsdominoes,aurora,21.02.2025 23:51,file:///var/home/winsdominoes/.var/app/org.libreoffice.LibreOffice/config/libreoffice/4; \ No newline at end of file diff --git a/spring-2025/hcd-201/HCD-201:00010 - Understanding and Applying ACM Code of Ethics - Thanawin Pattanaphol.odt b/spring-2025/hcd-201/HCD-201:00010 - Understanding and Applying ACM Code of Ethics - Thanawin Pattanaphol.odt new file mode 100644 index 0000000000000000000000000000000000000000..b2f4c690c6fde676de9865a293b640553c7d113b GIT binary patch literal 41666 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

rs4#g%b@nYowTcJc*TPjBTdV?b?3GAn1t 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 literal 0 HcmV?d00001 diff --git a/spring-2025/sen-109/00010/rust-chat-server/server/Cargo.toml b/spring-2025/sen-109/00010/rust-chat-server/server/Cargo.toml index 98c09ba..b2907c1 100644 --- a/spring-2025/sen-109/00010/rust-chat-server/server/Cargo.toml +++ b/spring-2025/sen-109/00010/rust-chat-server/server/Cargo.toml @@ -1,19 +1,21 @@ -[package] -name = "server" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -anyhow = "1.0.75" -comms = { path = "../comms", features = ["server"] } -nanoid = "0.4.0" -serde = "1.0" -serde_json = "1.0" -tokio = { version = "1.43.0", features = ["full"] } -tokio-stream = { version = "0.1.17" } - -[dev-dependencies] -comms = { path = "../comms", features = ["client"] } -rand = "0.8.5" +[package] +name = "server" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +anyhow = "1.0.75" +circular-queue = "0.2.6" +comms = { path = "../comms", features = ["server"] } +futures = "0.3.31" +nanoid = "0.4.0" +serde = "1.0" +serde_json = "1.0" +tokio = { version = "1.43.0", features = ["full"] } +tokio-stream = { version = "0.1.17" } + +[dev-dependencies] +comms = { path = "../comms", features = ["client"] } +rand = "0.8.5" diff --git a/spring-2025/sen-109/00010/rust-chat-server/server/src/room_manager/mod.rs b/spring-2025/sen-109/00010/rust-chat-server/server/src/room_manager/mod.rs index c058c79..2680aea 100644 --- a/spring-2025/sen-109/00010/rust-chat-server/server/src/room_manager/mod.rs +++ b/spring-2025/sen-109/00010/rust-chat-server/server/src/room_manager/mod.rs @@ -1,12 +1,16 @@ use std::sync::Arc; +use std::thread; use tokio::sync::Mutex; +use tokio::runtime::Runtime; use self::room::ChatRoom; pub use self::room::{ChatRoomMetadata, SessionAndUserId, UserSessionHandle}; pub use self::room_manager::RoomManager; +use futures::executor; + mod room; #[allow(clippy::module_inception)] mod room_manager; @@ -25,9 +29,10 @@ impl RoomManagerBuilder { /// Add a room to the room manager /// Will panic if a room with the same name already exists + pub fn create_room(mut self, metadata: ChatRoomMetadata) -> Self { let chat_room = Arc::new(Mutex::new(ChatRoom::new(metadata.clone()))); - + if self .chat_rooms .iter() @@ -36,7 +41,9 @@ impl RoomManagerBuilder { panic!("room with the same name already exists"); } - self.chat_rooms.push((metadata, chat_room)); + self.chat_rooms.push((metadata.clone(), chat_room)); + + ChatRoom::listen_messages(&mut ChatRoom::new(metadata)); self } diff --git a/spring-2025/sen-109/00010/rust-chat-server/server/src/room_manager/room/chat_room.rs b/spring-2025/sen-109/00010/rust-chat-server/server/src/room_manager/room/chat_room.rs index b6be756..84762e8 100644 --- a/spring-2025/sen-109/00010/rust-chat-server/server/src/room_manager/room/chat_room.rs +++ b/spring-2025/sen-109/00010/rust-chat-server/server/src/room_manager/room/chat_room.rs @@ -1,6 +1,7 @@ use comms::event::{self, Event}; use serde::{Deserialize, Serialize}; use tokio::sync::broadcast; +use circular_queue::CircularQueue; use super::{ user_registry::UserRegistry, user_session_handle::UserSessionHandle, SessionAndUserId, @@ -13,6 +14,12 @@ pub struct ChatRoomMetadata { pub description: String, } +#[derive(Debug, Clone)] +pub enum MessageBoxItem { + Message { user_id: String, content: String }, + Notification(String), +} + const BROADCAST_CHANNEL_CAPACITY: usize = 100; #[derive(Debug)] @@ -22,6 +29,7 @@ pub struct ChatRoom { metadata: ChatRoomMetadata, broadcast_tx: broadcast::Sender, user_registry: UserRegistry, + messages: CircularQueue } impl ChatRoom { @@ -32,6 +40,7 @@ impl ChatRoom { metadata, broadcast_tx, user_registry: UserRegistry::new(), + messages: CircularQueue::with_capacity(10) } } @@ -39,15 +48,24 @@ impl ChatRoom { self.user_registry.get_unique_user_ids() } - pub async fn store_message(&self) { - let broadcast_tx = self.broadcast_tx.clone(); - let mut broadcast_rx = broadcast_tx.subscribe(); - - let message_data = broadcast_rx.recv().await.unwrap(); - - println!("{:?}", message_data); + pub fn store_message(&mut self, user_id: String, content: String) + { + self.messages.push(MessageBoxItem::Message{user_id, content}); + println!("{:#?}", self.messages); } + pub async fn listen_messages(&mut self) + { + let mut broadcast_rx = self.broadcast_tx.subscribe(); + + while let Ok(event) = broadcast_rx.recv().await + { + if let Event::UserMessage(event) = event + { + self.store_message(event.user_id.clone(), event.content.clone()); + } + } + } /// Add a participant to the room and broadcast that they joined /// diff --git a/spring-2025/sen-109/00010/rust-chat-server/server/src/room_manager/room/user_session_handle.rs b/spring-2025/sen-109/00010/rust-chat-server/server/src/room_manager/room/user_session_handle.rs index ffded59..4ddb0cb 100644 --- a/spring-2025/sen-109/00010/rust-chat-server/server/src/room_manager/room/user_session_handle.rs +++ b/spring-2025/sen-109/00010/rust-chat-server/server/src/room_manager/room/user_session_handle.rs @@ -1,7 +1,6 @@ use anyhow::Context; use comms::event; use tokio::sync::broadcast; -use super::chat_room; #[derive(Debug, Clone)] pub struct SessionAndUserId { @@ -59,8 +58,6 @@ impl UserSessionHandle { }, )) .context("could not write to the broadcast channel")?; - - chat_room::store_message(); Ok(()) }