implemented basic messageing system for clients.
This commit is contained in:
parent
a493eddd50
commit
e92096b6ad
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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<Option<TcpStream>>,
|
||||
|
||||
#[serde(skip)]
|
||||
stream_reader: Mutex<Option<BufReader<TcpStream>>>,
|
||||
|
||||
#[serde(skip)]
|
||||
stream_writer: Mutex<Option<BufWriter<TcpStream>>>,
|
||||
|
||||
}
|
||||
|
||||
// client funciton implmentations
|
||||
impl IClient<ClientMessage> for Client {
|
||||
fn new(map: HashMap<String, String>, server_channel: Sender<ServerMessages> ) -> Arc<Client> {
|
||||
fn new(map: HashMap<String, String>, stream: TcpStream, server_channel: Sender<ServerMessages> ) -> Arc<Client> {
|
||||
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<ClientMessage> 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<ClientMessage> 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::<ClientSocketMessage>(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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<TClientMessage> {
|
||||
fn new(map: HashMap<String, String>, server_channel: Sender<ServerMessages> ) -> Arc<Self>;
|
||||
fn new(map: HashMap<String, String>, stream: TcpStream, server_channel: Sender<ServerMessages> ) -> Arc<Self>;
|
||||
|
||||
fn send(&self, bytes: Vec<u8>) -> Result<(), &str>;
|
||||
fn recv(&self) -> Option<Vec<u8>>;
|
||||
|
|
|
|||
Loading…
Reference in New Issue