implemented basic connection handling in the server

This commit is contained in:
michael-bailey 2021-03-16 10:11:31 +00:00
parent 6c89f34151
commit 71fe467ca2
5 changed files with 68 additions and 60 deletions

View File

@ -32,7 +32,7 @@ pub enum ClientMessage {
/// ///
/// - stream: The socket for the connected client. /// - stream: The socket for the connected client.
/// - owner: An optional reference to the owning object. /// - owner: An optional reference to the owning object.
#[derive(Serialize)] #[derive(Debug, Serialize)]
pub struct Client { pub struct Client {
pub uuid: Uuid, pub uuid: Uuid,
username: String, username: String,

View File

@ -1,6 +1,8 @@
pub mod client; pub mod client;
mod traits; mod traits;
// use crate::lib::server::ServerMessages;
use crate::lib::server::ServerMessages;
use std::sync::Arc; use std::sync::Arc;
use std::sync::Mutex; use std::sync::Mutex;
use std::sync::Weak; use std::sync::Weak;
@ -19,69 +21,45 @@ enum ClientManagerMessages {}
/// # ClientManager /// # ClientManager
/// This struct manages all connected users /// This struct manages all connected users
#[derive(Debug)]
pub struct ClientManager { pub struct ClientManager {
clients: Mutex<Vec<Arc<Client>>>, clients: Mutex<Vec<Arc<Client>>>,
weak_self: Mutex<Option<Weak<Self>>>, // weak_self: Mutex<Option<Weak<Self>>>,
server_ref: Mutex<Option<Weak<Server>>,
server_channel: Sender<ServerMessages>,
sender: Sender<ClientManagerMessages>, sender: Sender<ClientManagerMessages>,
receiver: Receiver<ClientManagerMessages>, receiver: Receiver<ClientManagerMessages>,
} }
impl ClientManager { impl ClientManager {
pub fn new() -> Arc<Self> { pub fn new(server_channel: Sender<ServerMessages>) -> Arc<Self> {
let channels = unbounded(); let (sender, receiver) = unbounded();
let manager_ref: Arc<Self> = Arc::new(ClientManager { Arc::new(ClientManager {
clients: Mutex::default(), clients: Mutex::default(),
weak_self: Mutex::default(), server_channel,
sender: channels.0, sender,
receiver: channels.1, receiver,
}); })
// get the reference
{
let mut lock = manager_ref.weak_self.lock().unwrap();
let tmp = manager_ref.clone();
*lock = Some(Arc::downgrade(&tmp));
}
manager_ref.set_ref(manager_ref.clone());
manager_ref
}
fn set_ref(&self, reference: Arc<Self>) {
let mut lock = self.weak_self.lock().unwrap();
*lock = Some(Arc::downgrade(&reference));
} }
} }
impl TClientManager<Client, ClientMessage> for ClientManager { impl TClientManager<Client, ClientMessage> for ClientManager {
fn add_client(&self, client: std::sync::Arc<Client>) { fn add_client(&self, client: std::sync::Arc<Client>) {
self.add_child(client); self.clients.lock().unwrap().push(client);
} }
fn remove_client(&self, uuid: Uuid) { fn remove_client(&self, _uuid: Uuid) {
let mut client_list = self.clients.lock().unwrap(); self.clients.lock().unwrap().sort();
client_list.sort();
if let Ok(index) = client_list.binary_search_by(move |client| client.uuid.cmp(&uuid)) {
client_list.remove(index);
}
} }
fn message_client(&self, id: Uuid, msg: ClientMessage) -> Result<(), &str> { fn message_client(&self, _id: Uuid, _msg: ClientMessage) {
let mut client_list = self.clients.lock().unwrap(); todo!()
client_list.sort();
if let Ok(index) = client_list.binary_search_by(move |client| client.uuid.cmp(&id)) {
if let Some(client) = client_list.get(index) {
let _ = client.send_message(msg);
}
}
Ok(())
} }
fn tick(&self) { fn tick(&self) {
@ -90,16 +68,6 @@ impl TClientManager<Client, ClientMessage> for ClientManager {
} }
} }
impl IOwner<Client> for ClientManager{
fn add_child(&self, child: Arc<Client>) {
child.set_owner(self.get_ref());
self.clients.lock().unwrap().push(child);
}
fn get_ref(&self) -> Weak<Self> {
self.weak_self.lock().unwrap().unwrap().clone()
}
}
#[cfg(test)] #[cfg(test)]
mod test { mod test {
@ -109,9 +77,9 @@ mod test {
#[test] #[test]
fn test_get_ref() { fn test_get_ref() {
let client_manager = ClientManager::new(); // let client_manager = ClientManager::new();
let _cm_ref = client_manager.get_ref(); // let _cm_ref = client_manager.get_ref();
assert_eq!(Arc::weak_count(&client_manager), 2); // assert_eq!(Arc::weak_count(&client_manager), 2);
} }
#[test] #[test]

View File

@ -8,6 +8,6 @@ use uuid::Uuid;
pub trait TClientManager<TClient,TClientMessage> { pub trait TClientManager<TClient,TClientMessage> {
fn add_client(&self, client: Arc<TClient>); fn add_client(&self, client: Arc<TClient>);
fn remove_client(&self, id: Uuid); fn remove_client(&self, id: Uuid);
fn message_client(&self, id: Uuid, msg: TClientMessage) -> Result<(), &str>; fn message_client(&self, id: Uuid, msg: TClientMessage);
fn tick(&self, ); fn tick(&self, );
} }

View File

@ -1,15 +1,21 @@
pub mod client_management; pub mod client_management;
use crossbeam_channel::{Sender, Receiver, unbounded};
use std::sync::{Arc, Weak, Mutex}; use std::sync::{Arc, Weak, Mutex};
use std::net::TcpListener; use std::net::TcpListener;
use std::io::Write;
use std::io::Read;
use crossbeam_channel::{Sender, Receiver, unbounded};
use crate::lib::server::client_management::ClientManager; use crate::lib::server::client_management::ClientManager;
use crate::lib::Foundation::{IOwner, IOwned, ICooperative}; use crate::lib::Foundation::{IOwner, IOwned, ICooperative};
use client_management::client::Client; use client_management::client::Client;
use crate::lib::commands::Commands;
enum ServerMessages { #[derive(Debug)]
ClientConnected(Client), pub enum ServerMessages {
ClientConnected(Arc<Client>),
} }
pub struct Server { pub struct Server {
@ -27,7 +33,7 @@ impl Server {
Arc::new(Server { Arc::new(Server {
server_socket: listener, server_socket: listener,
client_manager: ClientManager::new(sender), client_manager: ClientManager::new(sender.clone()),
sender, sender,
receiver, receiver,
@ -38,5 +44,34 @@ impl Server {
impl ICooperative for Server{ impl ICooperative for Server{
fn tick(&self) { fn tick(&self) {
let mut buffer = vec![0; 1024];
// get connections
for connection in self.server_socket.incoming() {
match connection {
Ok(mut stream) => {
let _ = stream.write(Commands::Request(None).to_string().as_bytes());
let _ = stream.read(&mut buffer);
let command = Commands::from(&mut buffer);
match command {
Commands::Info(None) => {let _ = stream.write("todo".as_bytes());}
_ => {let _ = stream.write("not implemented!".as_bytes());}
}
},
_ => println!("!connection error occured!"),
}
}
// message loop
for message in self.receiver.iter() {
match message {
ServerMessages::ClientConnected(client) => println!("client connected: {:?}", client),
}
}
} }
} }

View File

@ -3,6 +3,7 @@ mod lib;
use clap::{App, Arg}; use clap::{App, Arg};
use crate::lib::server::Server; use crate::lib::server::Server;
use crate::lib::Foundation::ICooperative;
fn main() { fn main() {
let _args = App::new("--rust chat server--") let _args = App::new("--rust chat server--")
@ -18,7 +19,11 @@ fn main() {
.takes_value(true)) .takes_value(true))
.get_matches(); .get_matches();
let mut server = Server::new(); let server = Server::new();
loop {
server.tick();
}
} }