adding support for updating clients

This commit is contained in:
michael-bailey 2021-04-09 21:23:52 +01:00
parent 48227aabe3
commit f60af38110
6 changed files with 65 additions and 7 deletions

View File

@ -1,2 +1,12 @@
pub mod messages;
pub mod prelude;
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct ClientDetails {
pub uuid: Uuid,
pub username: String,
pub address: String,
}

View File

@ -1,4 +1,6 @@
use crate::ClientDetails;
use serde::{Deserialize, Serialize};
use uuid::Uuid;
/// # ClientMessage
@ -23,5 +25,7 @@ pub enum ClientStreamOut {
UserMessage { from: Uuid, content: String },
GlobalMessage { content: String },
ConnectedClients {clients: Vec<ClientDetails>},
Disconnected,
}

View File

@ -1,5 +1,4 @@
use crate::messages::ClientMessage;
use crate::messages::ClientMessage::{Disconnect, Message};
use crate::messages::ServerMessage;
use foundation::prelude::IPreemptive;
use std::cmp::Ordering;
@ -15,6 +14,7 @@ use crossbeam_channel::{unbounded, Receiver, Sender};
use serde::Serialize;
use uuid::Uuid;
use foundation::ClientDetails;
use foundation::messages::client::{ClientStreamIn, ClientStreamOut};
use foundation::prelude::IMessagable;
@ -35,6 +35,7 @@ pub struct Client {
pub uuid: Uuid,
username: String,
address: String,
pub details: ClientDetails,
// non serializable
#[serde(skip)]
@ -71,9 +72,15 @@ impl Client {
let in_stream = stream.try_clone().unwrap();
Arc::new(Client {
username,
username: username.clone(),
uuid: Uuid::parse_str(&uuid).expect("invalid id"),
address,
address: address.clone(),
details: ClientDetails {
uuid: Uuid::parse_str(&uuid).expect("invalid id"),
username,
address,
},
server_channel: Mutex::new(Some(server_channel)),
@ -110,6 +117,7 @@ impl IPreemptive for Client {
let _ = std::thread::Builder::new()
.name(format!("client thread recv [{:?}]", &arc.uuid))
.spawn(move || {
use ClientMessage::{Disconnect};
let arc = arc1;
let mut buffer = String::new();
@ -167,6 +175,7 @@ impl IPreemptive for Client {
'main: loop {
for message in arc.output.iter() {
use ClientMessage::{Disconnect,Message, Update};
println!("[Client {:?}]: {:?}", &arc.uuid, message);
match message {
Disconnect => {
@ -191,6 +200,18 @@ impl IPreemptive for Client {
let _ = writer.write_all(&buffer);
let _ = writer.flush();
}
Update {clients} => {
let client_details_vec: Vec<ClientDetails> = clients.iter().map(|client| &client.details).cloned().collect();
let _ = writeln!(
buffer,
"{}",
serde_json::to_string(
&ClientStreamOut::ConnectedClients {clients: client_details_vec}
).unwrap()
);
let _ = writer.write_all(&buffer);
let _ = writer.flush();
}
}
}
}
@ -212,6 +233,12 @@ impl Default for Client {
uuid: Uuid::new_v4(),
address: "127.0.0.1".to_string(),
details: ClientDetails {
uuid: Uuid::new_v4(),
username: "generic_client".to_string(),
address: "127.0.0.1".to_string(),
},
output: reciever,
input: sender,

View File

@ -59,7 +59,7 @@ impl IPreemptive for ClientManager {
if !arc.receiver.is_empty() {
for message in arc.receiver.try_iter() {
println!("[Client manager]: recieved message: {:?}", message);
use ClientMgrMessage::{Add, Remove, SendMessage};
use ClientMgrMessage::{Add, Remove, SendMessage, SendClients};
match message {
Add(client) => {
@ -69,7 +69,7 @@ impl IPreemptive for ClientManager {
if lock.insert(client.uuid, client).is_none() {
println!("value is new");
}
}
},
Remove(uuid) => {
println!("[Client Manager]: removing client: {:?}", &uuid);
if let Some(client) =
@ -77,7 +77,7 @@ impl IPreemptive for ClientManager {
{
client.send_message(ClientMessage::Disconnect);
}
}
},
SendMessage { to, from, content } => {
let lock = arc.clients.lock().unwrap();
if let Some(client) = lock.get(&to) {
@ -86,7 +86,19 @@ impl IPreemptive for ClientManager {
content,
})
}
}
},
SendClients {to} => {
let lock = arc.clients.lock().unwrap();
if let Some(client) = lock.get(&to) {
let clients_vec: Vec<Arc<Client>> = lock.values().cloned().collect();
client.send_message(ClientMessage::Update {
clients: clients_vec,
})
}
},
#[allow(unreachable_patterns)]
_ => println!("[Client manager]: not implemented"),
}

View File

@ -7,6 +7,8 @@ use crate::client::Client;
pub enum ClientMessage {
Message { from: Uuid, content: String },
Update {clients: Vec<Arc<Client>>},
Disconnect,
}
@ -14,6 +16,7 @@ pub enum ClientMessage {
pub enum ClientMgrMessage {
Remove(Uuid),
Add(Arc<Client>),
SendClients {to: Uuid},
SendMessage {
from: Uuid,
to: Uuid,
@ -30,4 +33,5 @@ pub enum ServerMessage {
content: String,
},
ClientDisconnected(Uuid),
ClientUpdate(Uuid),
}

View File

@ -58,6 +58,7 @@ impl ICooperative for Server {
ServerMessage::ClientSendMessage { from, to, content } => self
.client_manager
.send_message(SendMessage { from, to, content }),
ServerMessage::ClientUpdate (_uuid) => println!("not implemented"),
}
}
}