implemented basic connection handling in the server
This commit is contained in:
parent
6c89f34151
commit
71fe467ca2
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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]
|
||||||
|
|
|
||||||
|
|
@ -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, );
|
||||||
}
|
}
|
||||||
|
|
@ -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),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue