adding user update support
This commit is contained in:
parent
5aa4f8caf6
commit
9299d2e335
|
|
@ -6,7 +6,7 @@ use uuid::Uuid;
|
|||
|
||||
#[derive(Deserialize, Serialize, Debug, Clone)]
|
||||
pub struct ClientDetails {
|
||||
pub uuid: Uuid,
|
||||
pub username: String,
|
||||
pub address: String,
|
||||
}
|
||||
pub uuid: Uuid,
|
||||
pub username: String,
|
||||
pub address: String,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ pub enum ClientStreamOut {
|
|||
UserMessage { from: Uuid, content: String },
|
||||
GlobalMessage { content: String },
|
||||
|
||||
ConnectedClients {clients: Vec<ClientDetails>},
|
||||
ConnectedClients { clients: Vec<ClientDetails> },
|
||||
|
||||
Disconnected,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
hard_tabs = true
|
||||
max_width = 90
|
||||
max_width = 100
|
||||
|
|
@ -13,6 +13,7 @@ serde = { version = "1.0", features = ["derive"] }
|
|||
serde_json = "1.0"
|
||||
crossbeam = "0.8.0"
|
||||
crossbeam-channel = "0.5.0"
|
||||
zeroize = "1.1.0"
|
||||
|
||||
[dependencies.foundation]
|
||||
path = '../foundation'
|
||||
|
|
@ -13,10 +13,11 @@ use std::sync::Mutex;
|
|||
use crossbeam_channel::{unbounded, Receiver, Sender};
|
||||
use serde::Serialize;
|
||||
use uuid::Uuid;
|
||||
use zeroize::Zeroize;
|
||||
|
||||
use foundation::ClientDetails;
|
||||
use foundation::messages::client::{ClientStreamIn, ClientStreamOut};
|
||||
use foundation::prelude::IMessagable;
|
||||
use foundation::ClientDetails;
|
||||
|
||||
/// # Client
|
||||
/// This struct represents a connected user.
|
||||
|
|
@ -117,7 +118,7 @@ impl IPreemptive for Client {
|
|||
let _ = std::thread::Builder::new()
|
||||
.name(format!("client thread recv [{:?}]", &arc.uuid))
|
||||
.spawn(move || {
|
||||
use ClientMessage::{Disconnect};
|
||||
use ClientMessage::Disconnect;
|
||||
let arc = arc1;
|
||||
|
||||
let mut buffer = String::new();
|
||||
|
|
@ -131,6 +132,7 @@ impl IPreemptive for Client {
|
|||
}
|
||||
|
||||
let command = serde_json::from_str::<ClientStreamIn>(buffer.as_str());
|
||||
println!("[Client {:?}]: recieved {}", arc.uuid, &buffer);
|
||||
match command {
|
||||
Ok(ClientStreamIn::Disconnect) => {
|
||||
println!("[Client {:?}]: Disconnect recieved", &arc.uuid);
|
||||
|
|
@ -138,10 +140,7 @@ impl IPreemptive for Client {
|
|||
break 'main;
|
||||
}
|
||||
Ok(ClientStreamIn::SendMessage { to, content }) => {
|
||||
println!(
|
||||
"[Client {:?}]: send message to: {:?}",
|
||||
&arc.uuid, &to
|
||||
);
|
||||
println!("[Client {:?}]: send message to: {:?}", &arc.uuid, &to);
|
||||
let lock = arc.server_channel.lock().unwrap();
|
||||
let sender = lock.as_ref().unwrap();
|
||||
let _ = sender.send(ServerMessage::ClientSendMessage {
|
||||
|
|
@ -150,8 +149,14 @@ impl IPreemptive for Client {
|
|||
content,
|
||||
});
|
||||
}
|
||||
Ok(ClientStreamIn::Update) => {
|
||||
let lock = arc.server_channel.lock().unwrap();
|
||||
let sender = lock.as_ref().unwrap();
|
||||
let _ = sender.send(ServerMessage::ClientUpdate { to: arc.uuid });
|
||||
}
|
||||
_ => println!("[Client {:?}]: command not found", &arc.uuid),
|
||||
}
|
||||
buffer.zeroize();
|
||||
}
|
||||
println!("[Client {:?}] exited thread 1", &arc.uuid);
|
||||
});
|
||||
|
|
@ -175,7 +180,7 @@ impl IPreemptive for Client {
|
|||
|
||||
'main: loop {
|
||||
for message in arc.output.iter() {
|
||||
use ClientMessage::{Disconnect,Message, Update};
|
||||
use ClientMessage::{Disconnect, Message, SendClients};
|
||||
println!("[Client {:?}]: {:?}", &arc.uuid, message);
|
||||
match message {
|
||||
Disconnect => {
|
||||
|
|
@ -184,35 +189,33 @@ impl IPreemptive for Client {
|
|||
.unwrap()
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.send(ServerMessage::ClientDisconnected(arc.uuid))
|
||||
.send(ServerMessage::ClientDisconnected { id: arc.uuid })
|
||||
.unwrap();
|
||||
break 'main;
|
||||
}
|
||||
Message { from, content } => {
|
||||
let _ = writeln!(
|
||||
buffer,
|
||||
"{}",
|
||||
serde_json::to_string(
|
||||
&ClientStreamOut::UserMessage { from, content }
|
||||
)
|
||||
.unwrap()
|
||||
);
|
||||
let msg = &ClientStreamOut::UserMessage { from, content };
|
||||
let _ = writeln!(buffer, "{}", serde_json::to_string(msg).unwrap());
|
||||
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()
|
||||
);
|
||||
SendClients { clients } => {
|
||||
let client_details_vec: Vec<ClientDetails> = clients
|
||||
.iter()
|
||||
.map(|client| &client.details)
|
||||
.cloned()
|
||||
.collect();
|
||||
|
||||
let msg = &ClientStreamOut::ConnectedClients {
|
||||
clients: client_details_vec,
|
||||
};
|
||||
|
||||
let _ = writeln!(buffer, "{}", serde_json::to_string(msg).unwrap());
|
||||
let _ = writer.write_all(&buffer);
|
||||
let _ = writer.flush();
|
||||
}
|
||||
}
|
||||
buffer.zeroize();
|
||||
}
|
||||
}
|
||||
println!("[Client {:?}]: exited thread 2", &arc.uuid);
|
||||
|
|
|
|||
|
|
@ -39,6 +39,13 @@ impl ClientManager {
|
|||
receiver,
|
||||
})
|
||||
}
|
||||
|
||||
fn send_to_client(&self, id: &Uuid, msg: ClientMessage) {
|
||||
let lock = self.clients.lock().unwrap();
|
||||
if let Some(client) = lock.get(id) {
|
||||
client.send_message(msg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl IMessagable<ClientMgrMessage, Sender<ServerMessage>> for ClientManager {
|
||||
|
|
@ -59,7 +66,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, SendClients};
|
||||
use ClientMgrMessage::{Add, Remove, SendClients, SendMessage};
|
||||
|
||||
match message {
|
||||
Add(client) => {
|
||||
|
|
@ -69,35 +76,27 @@ 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) =
|
||||
arc.clients.lock().unwrap().remove(&uuid)
|
||||
{
|
||||
if let Some(client) = arc.clients.lock().unwrap().remove(&uuid) {
|
||||
client.send_message(ClientMessage::Disconnect);
|
||||
}
|
||||
},
|
||||
}
|
||||
SendMessage { to, from, content } => {
|
||||
arc.send_to_client(&to, ClientMessage::Message { from, content })
|
||||
}
|
||||
SendClients { to } => {
|
||||
let lock = arc.clients.lock().unwrap();
|
||||
if let Some(client) = lock.get(&to) {
|
||||
client.send_message(ClientMessage::Message {
|
||||
from,
|
||||
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();
|
||||
let clients_vec: Vec<Arc<Client>> =
|
||||
lock.values().cloned().collect();
|
||||
|
||||
client.send_message(ClientMessage::Update {
|
||||
client.send_message(ClientMessage::SendClients {
|
||||
clients: clients_vec,
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
}
|
||||
|
||||
#[allow(unreachable_patterns)]
|
||||
_ => println!("[Client manager]: not implemented"),
|
||||
|
|
|
|||
|
|
@ -11,17 +11,20 @@ use server::Server;
|
|||
|
||||
fn main() {
|
||||
let _args = App::new("--rust chat server--")
|
||||
.version("0.1.5")
|
||||
.author("Mitchel Hardie <mitch161>, Michael Bailey <michael-bailey>")
|
||||
.about("this is a chat server developed in rust, depending on the version one of two implementations will be used")
|
||||
.arg(
|
||||
Arg::with_name("config")
|
||||
.short("p")
|
||||
.long("port")
|
||||
.value_name("PORT")
|
||||
.help("sets the port the server runs on.")
|
||||
.takes_value(true))
|
||||
.get_matches();
|
||||
.version("0.1.5")
|
||||
.author("Mitchel Hardie <mitch161>, Michael Bailey <michael-bailey>")
|
||||
.about(
|
||||
"this is a chat server developed in rust, depending on the version one of two implementations will be used",
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("config")
|
||||
.short("p")
|
||||
.long("port")
|
||||
.value_name("PORT")
|
||||
.help("sets the port the server runs on.")
|
||||
.takes_value(true),
|
||||
)
|
||||
.get_matches();
|
||||
|
||||
let server = Server::new();
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ use crate::client::Client;
|
|||
pub enum ClientMessage {
|
||||
Message { from: Uuid, content: String },
|
||||
|
||||
Update {clients: Vec<Arc<Client>>},
|
||||
SendClients { clients: Vec<Arc<Client>> },
|
||||
|
||||
Disconnect,
|
||||
}
|
||||
|
|
@ -16,7 +16,9 @@ pub enum ClientMessage {
|
|||
pub enum ClientMgrMessage {
|
||||
Remove(Uuid),
|
||||
Add(Arc<Client>),
|
||||
SendClients {to: Uuid},
|
||||
SendClients {
|
||||
to: Uuid,
|
||||
},
|
||||
SendMessage {
|
||||
from: Uuid,
|
||||
to: Uuid,
|
||||
|
|
@ -26,12 +28,18 @@ pub enum ClientMgrMessage {
|
|||
|
||||
#[derive(Debug)]
|
||||
pub enum ServerMessage {
|
||||
ClientConnected(Arc<Client>),
|
||||
ClientConnected {
|
||||
client: Arc<Client>,
|
||||
},
|
||||
ClientSendMessage {
|
||||
from: Uuid,
|
||||
to: Uuid,
|
||||
content: String,
|
||||
},
|
||||
ClientDisconnected(Uuid),
|
||||
ClientUpdate(Uuid),
|
||||
ClientDisconnected {
|
||||
id: Uuid,
|
||||
},
|
||||
ClientUpdate {
|
||||
to: Uuid,
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,10 +19,7 @@ pub struct NetworkManager {
|
|||
}
|
||||
|
||||
impl NetworkManager {
|
||||
pub fn new(
|
||||
port: String,
|
||||
server_channel: Sender<ServerMessage>,
|
||||
) -> Arc<NetworkManager> {
|
||||
pub fn new(port: String, server_channel: Sender<ServerMessage>) -> Arc<NetworkManager> {
|
||||
let mut address = "0.0.0.0:".to_string();
|
||||
address.push_str(&port);
|
||||
|
||||
|
|
@ -63,8 +60,7 @@ impl IPreemptive for NetworkManager {
|
|||
let _ = writeln!(
|
||||
out_buffer,
|
||||
"{}",
|
||||
serde_json::to_string(&NetworkSockOut::Request)
|
||||
.unwrap()
|
||||
serde_json::to_string(&NetworkSockOut::Request).unwrap()
|
||||
);
|
||||
|
||||
let _ = writer.write_all(&out_buffer);
|
||||
|
|
@ -112,9 +108,9 @@ impl IPreemptive for NetworkManager {
|
|||
server_channel.clone(),
|
||||
);
|
||||
server_channel
|
||||
.send(ServerMessage::ClientConnected(
|
||||
new_client,
|
||||
))
|
||||
.send(ServerMessage::ClientConnected {
|
||||
client: new_client,
|
||||
})
|
||||
.unwrap_or_default();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,17 +48,19 @@ impl ICooperative for Server {
|
|||
for message in self.receiver.try_iter() {
|
||||
println!("[server]: received message {:?}", &message);
|
||||
match message {
|
||||
ServerMessage::ClientConnected(client) => {
|
||||
ServerMessage::ClientConnected { client } => {
|
||||
self.client_manager.send_message(Add(client))
|
||||
}
|
||||
ServerMessage::ClientDisconnected(uuid) => {
|
||||
println!("disconnecting client {:?}", uuid);
|
||||
self.client_manager.send_message(Remove(uuid));
|
||||
ServerMessage::ClientDisconnected { id } => {
|
||||
println!("disconnecting client {:?}", id);
|
||||
self.client_manager.send_message(Remove(id));
|
||||
}
|
||||
ServerMessage::ClientSendMessage { from, to, content } => self
|
||||
.client_manager
|
||||
.send_message(SendMessage { from, to, content }),
|
||||
ServerMessage::ClientUpdate (_uuid) => println!("not implemented"),
|
||||
ServerMessage::ClientUpdate { to } => self
|
||||
.client_manager
|
||||
.send_message(ClientMgrMessage::SendClients { to }),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue