adding messaging support between clients

This commit is contained in:
michael-bailey 2021-03-30 16:23:49 +00:00
parent 1decf77207
commit a08b0b1805
6 changed files with 44 additions and 14 deletions

View File

@ -1,4 +1,6 @@
use uuid::Uuid;
use serde::{Deserialize, Serialize};
use uuid::Uuid;
/// # ClientMessage
/// This enum defined the message that a client can receive from the server
@ -9,7 +11,7 @@ pub enum ClientStreamIn {
Connected,
Update,
SendMessage { to_uuid: String, contents: String },
SendMessage { to_uuid: Uuid, contents: String },
SendGlobalMessage { contents: String },
Disconnect,

View File

@ -1,5 +1,5 @@
use crate::messages::ClientMessage;
use crate::messages::ClientMessage::Disconnect;
use crate::messages::ClientMessage::{Disconnect, Message};
use crate::messages::ServerMessage;
use foundation::prelude::IPreemptive;
use std::cmp::Ordering;
@ -27,6 +27,8 @@ use foundation::prelude::IMessagable;
/// - address: The the address of the connected client.
///
/// - stream: The socket for the connected client.
/// - stream_reader: the buffered reader used to receive messages
/// - stream_writer: the buffered writer used to send messages
/// - owner: An optional reference to the owning object.
#[derive(Debug, Serialize)]
pub struct Client {
@ -115,7 +117,10 @@ impl IPreemptive for Client {
let reader = reader_lock.as_mut().unwrap();
'main: while let Ok(size) = reader.read_line(&mut buffer) {
if size == 0 {arc.send_message(Disconnect); break 'main;}
if size == 0 {
arc.send_message(Disconnect);
break 'main;
}
let command = serde_json::from_str::<ClientStreamIn>(buffer.as_str());
match command {
@ -123,7 +128,13 @@ impl IPreemptive for Client {
println!("[Client {:?}]: Disconnect recieved", &arc.uuid);
arc.send_message(Disconnect);
break 'main;
}
},
Ok(ClientStreamIn::SendMessage{to_uuid, contents}) => {
println!("[Client {:?}]: send message to: {:?}",&arc.uuid, &to_uuid);
let lock = arc.server_channel.lock().unwrap();
let sender = lock.as_ref().unwrap();
sender.send(ServerMessage::ClientSendMessage {from: arc.uuid.clone(), to: to_uuid, contents });
},
_ => println!("[Client {:?}]: command not found", &arc.uuid),
}
}
@ -164,6 +175,14 @@ impl IPreemptive for Client {
.unwrap();
break 'main;
}
Message { from, contents } => {
writeln!(
buffer,
"{}",
serde_json::to_string(&ClientStreamOut::Connected)
.unwrap()
);
}
_ => println!(
"[Client {:?}]: message not implemented",
&arc.uuid

View File

@ -78,12 +78,10 @@ impl IPreemptive for ClientManager {
client.send_message(ClientMessage::Disconnect);
}
}
SendMessage(to_uuid, from_uuid, content) => {
SendMessage {to, from, contents} => {
let lock = arc.clients.lock().unwrap();
if let Some(client) = lock.get(&to_uuid) {
client.send_message(ClientMessage::Message(
from_uuid, content,
))
if let Some(client) = lock.get(&to) {
client.send_message(ClientMessage::Message { from, contents })
}
}
#[allow(unreachable_patterns)]

View File

@ -5,7 +5,7 @@ use crate::client::Client;
#[derive(Debug)]
pub enum ClientMessage {
Message(Uuid, String),
Message { from: Uuid, contents: String },
Disconnect,
}
@ -14,11 +14,20 @@ pub enum ClientMessage {
pub enum ClientMgrMessage {
Remove(Uuid),
Add(Arc<Client>),
SendMessage(Uuid, Uuid, String),
SendMessage {
from: Uuid,
to: Uuid,
contents: String,
},
}
#[derive(Debug)]
pub enum ServerMessage {
ClientConnected(Arc<Client>),
ClientSendMessage {
from: Uuid,
to: Uuid,
contents: String,
},
ClientDisconnected(Uuid),
}

View File

@ -36,8 +36,7 @@ impl NetworkManager {
}
impl IPreemptive for NetworkManager {
fn run(_: &Arc<Self>) {}
fn run(_: &Arc<Self>) {}
fn start(arc: &Arc<Self>) {
let arc = arc.clone();

View File

@ -44,7 +44,7 @@ impl Server {
impl ICooperative for Server {
fn tick(&self) {
use ClientMgrMessage::{Add, Remove};
use ClientMgrMessage::{Add, Remove, SendMessage};
// handle new messages loop
if !self.receiver.is_empty() {
@ -59,6 +59,9 @@ impl ICooperative for Server {
println!("disconnecting client {:?}", uuid);
self.client_manager.send_message(Remove(uuid));
}
ServerMessage::ClientSendMessage { from, to, contents } => self
.client_manager
.send_message(SendMessage { from, to, contents }),
}
}
}