diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..fa28d90 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,102 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "lldb", + "request": "launch", + "name": "Debug unit tests in library 'scct_migrations'", + "cargo": { + "args": [ + "test", + "--no-run", + "--lib", + "--package=scct-migrations" + ], + "filter": { + "name": "scct_migrations", + "kind": "lib" + } + }, + "args": [], + "cwd": "${workspaceFolder}" + }, + { + "type": "lldb", + "request": "launch", + "name": "Debug unit tests in library 'scct_server'", + "cargo": { + "args": [ + "test", + "--no-run", + "--lib", + "--package=scct-server" + ], + "filter": { + "name": "scct_server", + "kind": "lib" + } + }, + "args": [], + "cwd": "${workspaceFolder}" + }, + { + "type": "lldb", + "request": "launch", + "name": "Debug unit tests in library 'scct_model'", + "cargo": { + "args": [ + "test", + "--no-run", + "--lib", + "--package=scct-model" + ], + "filter": { + "name": "scct_model", + "kind": "lib" + } + }, + "args": [], + "cwd": "${workspaceFolder}" + }, + { + "type": "lldb", + "request": "launch", + "name": "Debug executable 'scct' server", + "cargo": { + "args": [ + "build", + "--bin=scct", + "--package=scct-cli" + ], + "filter": { + "name": "scct", + "kind": "bin" + } + }, + "args": ["--debug", "serve"], + "cwd": "${workspaceFolder}" + }, + { + "type": "lldb", + "request": "launch", + "name": "Debug unit tests in executable 'scct'", + "cargo": { + "args": [ + "test", + "--no-run", + "--bin=scct", + "--package=scct-cli" + ], + "filter": { + "name": "scct", + "kind": "bin" + } + }, + "args": [], + "cwd": "${workspaceFolder}" + } + ] +} \ No newline at end of file diff --git a/README.md b/README.md index 738fa7e..3d4d4d2 100644 --- a/README.md +++ b/README.md @@ -11,3 +11,20 @@ tldr: * sea_orm and sqlx are huge but ehh db flexibility is nice feature * i have no clue honestly * super cool chat thing yayyyyyyyy + +## Example serverbound messages + +### Request chat history of chat room + +The uuid is the chat room id + +```json +{"RequestChatHistory":"00000000-0000-0000-0000-000000000000"} +``` + +### Send message to a chat room + +```json +{"Message":{"id":"bef168ac-cee2-4319-9020-ef14a0778338","user_id":"67662e56-751a-4124-b611-0b54e53bd983","chat_id":"00000000-0000-0000-0000-000000000000","content":"hello world!","created":"2024-09-01T11:29:35.777275126Z","updated":null}} +``` + diff --git a/model/src/proto/c2s.rs b/model/src/proto/c2s.rs index a7a3ee5..cca0b4d 100644 --- a/model/src/proto/c2s.rs +++ b/model/src/proto/c2s.rs @@ -22,15 +22,15 @@ pub mod c { #[cfg(test)] mod test { #[test] - fn how_does_this_serialize_again() { + fn example_message() { panic!( "{}", serde_json::to_string( - &super::c::Packet::Message( + &super::s::Packet::Message( crate::messages::Model { id: uuid::Uuid::new_v4(), user_id: uuid::Uuid::new_v4(), - chat_id: uuid::Uuid::new_v4(), + chat_id: uuid::Uuid::nil(), content: Some("hello world!".to_string()), created: chrono::Utc::now(), updated: None, @@ -39,4 +39,16 @@ mod test { ).expect("uhmmm???") ) } + + #[test] + fn example_request_chat_history() { + panic!( + "{}", + serde_json::to_string( + &super::s::Packet::RequestChatHistory( + uuid::Uuid::nil() + ) + ).expect("uhmmm???") + ) + } } diff --git a/server/src/lib.rs b/server/src/lib.rs index c4d9f3b..8379226 100644 --- a/server/src/lib.rs +++ b/server/src/lib.rs @@ -4,7 +4,7 @@ use futures_util::FutureExt; use scct_model::{chats, messages, proto::c2s, users}; use sea_orm::{ActiveModelTrait, ConnectionTrait, DatabaseConnection, EntityTrait, IntoActiveModel, ColumnTrait, QueryFilter, QueryOrder}; use tokio::sync::Mutex; -use transport::{Transport, TransportSink, TransportStream, client_connection::ClientConnection}; +use transport::{Transport, client_connection::ClientConnection}; use uuid; pub mod transport; @@ -17,7 +17,7 @@ pub async fn serve(addr: &str, db_connection: DatabaseConnection) -> Result<(), tracing::info!("preparing C2S transport"); let mut listener = c2s.serve(addr.to_string()).await?; - // create the development chat if not exists + // create the dev-test chat if it doesn't exist if let Ok(None) = chats::Entity::find_by_id(uuid::Uuid::nil()).one(&db_connection).await { let chat = chats::Model { id: uuid::Uuid::nil(), // temporarily we have only one chat @@ -31,9 +31,9 @@ pub async fn serve(addr: &str, db_connection: DatabaseConnection) -> Result<(), tracing::info!("listening for connections"); while let Some((tx, rx)) = listener.recv().await { - let client = ClientConnection::new((tx, rx)); + let client = Arc::new(Mutex::new(ClientConnection::new((tx, rx)))); tracing::info!("new connection, starting handler"); - state.lock().await.push(&client); + state.lock().await.push(client.clone()); let _state = state.clone(); let handler_db_conn = db_connection.clone(); @@ -46,7 +46,7 @@ pub async fn serve(addr: &str, db_connection: DatabaseConnection) -> Result<(), } /// Connection handler for handling a connecting client -async fn handle_client_connection(active_client_peers: Arc>>, mut client: ClientConnection, db_connection: impl ConnectionTrait) { +async fn handle_client_connection(active_client_peers: Arc>>>>, client: Arc>, db_connection: impl ConnectionTrait) { // for now we're creating a new user for each connection let new_client_id = uuid::Uuid::new_v4(); let user = users::Model{ @@ -60,14 +60,16 @@ async fn handle_client_connection(active_client_peers: Arc { tracing::error!("error receiving from client: {e} -- stopping"); break; @@ -83,13 +85,14 @@ async fn handle_client_connection(active_client_peers: Arc { tracing::error!("failed to query all previously sent messages"); } Ok(messages) => { tracing::info!("responding to RequestChatHistory: {}", serde_json::to_string(&messages).unwrap()); - match client.tx.push(c2s::c::Packet::MessagesHistory(messages)).await { + match client.lock().await.tx.lock().await.push(c2s::c::Packet::MessagesHistory(messages)).await { Ok(_) => {tracing::debug!("responding to RequestChatHistory was successful.")}, Err(e) => {tracing::error!("Failed to respond to RequestChatHistory: {}", e)}, }; diff --git a/server/src/transport/client_connection.rs b/server/src/transport/client_connection.rs index 29e48bc..7f0fe76 100644 --- a/server/src/transport/client_connection.rs +++ b/server/src/transport/client_connection.rs @@ -7,14 +7,17 @@ // when the user logs out. // Basically lots of helper facilities. +use std::sync::Arc; + +use tokio::sync::Mutex; use uuid::Uuid; use super::{TransportSink, TransportStream}; pub struct ClientConnection { pub uuid: Uuid, - pub tx: Box, - pub rx: Box, + pub tx: Arc>, + pub rx: Arc>, pub user_uuid: Option // gets set if and only if a user is logged in with this connection } @@ -22,8 +25,8 @@ impl ClientConnection { pub fn new((tx, rx): (impl TransportSink + 'static, impl TransportStream + 'static)) -> ClientConnection { ClientConnection { uuid: Uuid::new_v4(), - tx: Box::new(tx), - rx: Box::new(rx), + tx: Arc::new(Mutex::new(tx)), + rx: Arc::new(Mutex::new(rx)), user_uuid: None, } }