diff --git a/Cargo.toml b/Cargo.toml index a2ee271..4d850dc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,6 +21,7 @@ log = "0.4" url = "2.2.0" uuid = {version = "0.8", features = ["serde", "v4"]} serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" [profile.dev] diff --git a/src/lib/server/client_management/client/mod.rs b/src/lib/server/client_management/client/mod.rs index 6dd9d14..416177f 100644 --- a/src/lib/server/client_management/client/mod.rs +++ b/src/lib/server/client_management/client/mod.rs @@ -7,16 +7,39 @@ use std::cmp::Ordering; use std::net::TcpStream; use std::sync::Mutex; use std::sync::Arc; +use std::io::{BufReader, BufWriter}; +use std::io::BufRead; use uuid::Uuid; -use serde::Serialize; +use serde::{Serialize, Deserialize}; use crossbeam_channel::{Sender, Receiver, unbounded}; use traits::IClient; use crate::lib::Foundation::{ICooperative, IMessagable}; use crate::lib::server::ServerMessages; -pub enum ClientMessage {} +/// # ClientMessage +/// This enum defined the message that a client can receive from the server +/// This uses the serde library to transform to and from json. +#[derive(Serialize, Deserialize)] +pub enum ClientMessage { + Disconnect {id: String}, + Update {id: String}, + + ServerMessage {id: String, msg: String}, + + NewMessage {id: String, from_user_id: String, msg: String}, + NewgroupMessage {id: String, from_group_id: String, from_user_id: String, msg: String}, +} + +/// # ClientSocketMessage +/// This enum defines a message that can be sent from a client to the server once connected +/// This uses the serde library to transform to and from json. +#[derive(Serialize, Deserialize)] +pub enum ClientSocketMessage { + Disconnect {id: String}, + SendMessage {id: String, to_user_id: String, msg: String} +} /// # Client /// This struct represents a connected user. @@ -46,13 +69,23 @@ pub struct Client { #[serde(skip)] stream: Mutex>, + + #[serde(skip)] + stream_reader: Mutex>>, + + #[serde(skip)] + stream_writer: Mutex>>, + } // client funciton implmentations impl IClient for Client { - fn new(map: HashMap, server_channel: Sender ) -> Arc { + fn new(map: HashMap, stream: TcpStream, server_channel: Sender ) -> Arc { let (sender, receiver) = unbounded(); + let out_stream = stream.try_clone().unwrap(); + let in_stream = stream.try_clone().unwrap(); + Arc::new(Client { username: map.get(&"name".to_string()).unwrap().clone(), uuid: Uuid::parse_str(map.get(&"uuid".to_string()).unwrap().as_str()).expect("invalid id"), @@ -63,7 +96,10 @@ impl IClient for Client { input: sender, output: receiver, - stream: Mutex::new(None), + stream: Mutex::new(Some(stream)), + + stream_reader: Mutex::new(Some(BufReader::new(in_stream))), + stream_writer: Mutex::new(Some(BufWriter::new(out_stream))), }) } @@ -82,6 +118,30 @@ impl IMessagable for Client{ // cooperative multitasking implementation impl ICooperative for Client { fn tick(&self) { + // aquire locks (so value isn't dropped) + let mut reader_lock = self.stream_reader.lock().unwrap(); + let mut writer_lock = self.stream_writer.lock().unwrap(); + + // aquiring mutable buffers + let reader = reader_lock.as_mut().unwrap(); + let _writer = writer_lock.as_mut().unwrap(); + + // create buffer + let mut buffer = String::new(); + + // loop over all lines that have been sent. + while let Ok(_size) = reader.read_line(&mut buffer) { + let command = serde_json::from_str::(buffer.as_str()).unwrap(); + + match command { + ClientSocketMessage::Disconnect {id} => println!("got Disconnect from id: {:?}", id), + _ => println!("New command found"), + } + } + + + // handle incomming messages + } } @@ -100,6 +160,9 @@ impl Default for Client { server_channel: None, stream: Mutex::new(None), + + stream_reader: Mutex::new(None), + stream_writer: Mutex::new(None), } } } diff --git a/src/lib/server/client_management/client/traits.rs b/src/lib/server/client_management/client/traits.rs index 07cc9a4..20a0fe8 100644 --- a/src/lib/server/client_management/client/traits.rs +++ b/src/lib/server/client_management/client/traits.rs @@ -1,4 +1,5 @@ use std::sync::Arc; +use std::net::TcpStream; use std::collections::HashMap; use crossbeam_channel::Sender; @@ -16,7 +17,7 @@ use crate::lib::server::ServerMessages; /// - send_msg: sends a event message to the client /// - recv_msg: used by the client to receive and process event messages pub trait IClient { - fn new(map: HashMap, server_channel: Sender ) -> Arc; + fn new(map: HashMap, stream: TcpStream, server_channel: Sender ) -> Arc; fn send(&self, bytes: Vec) -> Result<(), &str>; fn recv(&self) -> Option>;