ref-method and command merge #4
|
|
@ -15,6 +15,7 @@ crossbeam-utils = "0.7"
|
|||
crossbeam-queue = "0.2"
|
||||
dashmap = "3.11.4"
|
||||
async-std = "1.6.2"
|
||||
lazy_static = "1.4.0"
|
||||
|
||||
[profile.dev]
|
||||
opt-level = 0
|
||||
|
|
|
|||
25
src/main.rs
25
src/main.rs
|
|
@ -1,18 +1,23 @@
|
|||
#[macro_use]
|
||||
extern crate lazy_static;
|
||||
|
||||
mod server;
|
||||
// mod server_v2;
|
||||
|
||||
use crate::server::client::client_profile::Client;
|
||||
use crate::server::server_profile::Server;
|
||||
use std::net::{TcpStream, TcpListener};
|
||||
use rust_chat_server::ThreadPool;
|
||||
use std::sync::{Arc, Barrier, Mutex};
|
||||
use std::collections::HashMap;
|
||||
|
||||
fn main(){
|
||||
fn main(){
|
||||
lazy_static!{
|
||||
static ref server_name: &'static str = "Server-01";
|
||||
static ref server_address: &'static str = "0.0.0.0:6000";
|
||||
static ref server_author: &'static str = "noreply@email.com";
|
||||
static ref SERVER: Server<'static> = Server::new(&server_name, &server_address, &server_author);
|
||||
}
|
||||
/*
|
||||
let server_name = String::from("Server-01");
|
||||
let server_address = String::from("0.0.0.0:6000");
|
||||
let server_owner = String::from("noreply@email.com");
|
||||
let server_author = String::from("noreply@email.com");
|
||||
*/
|
||||
|
||||
let server = Server::new(&server_name, &server_address, &server_owner);
|
||||
server.start();
|
||||
//let server = Server::new(server_name, server_address, server_author);
|
||||
SERVER.start();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,28 +6,27 @@ use crate::server::commands::{Commands};
|
|||
use std::net::{Shutdown, TcpStream};
|
||||
use std::sync::Arc;
|
||||
use parking_lot::FairMutex;
|
||||
use std::collections::HashMap;
|
||||
use dashmap::DashMap;
|
||||
use std::io::prelude::*;
|
||||
use std::time::Duration;
|
||||
use regex::Regex;
|
||||
use crossbeam::{channel, Sender, Receiver, TryRecvError};
|
||||
use crossbeam::{Sender, Receiver, TryRecvError};
|
||||
use crossbeam_channel::unbounded;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Client<'client_lifetime> {
|
||||
|
||||
pub struct Client<'a> {
|
||||
connected: bool,
|
||||
stream: Arc<TcpStream>,
|
||||
uuid: String,
|
||||
username: String,
|
||||
address: String,
|
||||
server: &'client_lifetime Server<'client_lifetime>,
|
||||
server: &'a Server<'a>,
|
||||
tx_channel: Sender<Commands>,
|
||||
rx_channel: Receiver<Commands>,
|
||||
}
|
||||
|
||||
impl<'a> Client<'a> {
|
||||
pub fn new(server: &'a Server<'a>, stream: Arc<TcpStream>, uuid: &String, username: &String, address: &String) -> Client<'a>{
|
||||
pub fn new(server: &'a Server<'static>, stream: Arc<TcpStream>, uuid: &String, username: &String, address: &String) -> Self{
|
||||
let (tx_channel, rx_channel): (Sender<Commands>, Receiver<Commands>) = unbounded();
|
||||
|
||||
Client {
|
||||
|
|
@ -84,7 +83,7 @@ impl<'a> Client<'a> {
|
|||
Commands::Client(Some(params)) => {
|
||||
self.transmit_data(a.to_string().as_str());
|
||||
|
||||
let command = Commands::from(&buffer);
|
||||
/*let command = Commands::from(&buffer);
|
||||
match command{
|
||||
Commands::Success(None) => {
|
||||
println!("sucess confirmed");
|
||||
|
|
@ -94,6 +93,7 @@ impl<'a> Client<'a> {
|
|||
self.transmit_data(error.to_string().as_str());
|
||||
},
|
||||
}
|
||||
*/
|
||||
},
|
||||
Commands::Success(data) => {},
|
||||
_ => {},
|
||||
|
|
@ -113,7 +113,8 @@ impl<'a> Client<'a> {
|
|||
let command = Commands::from(incoming_message.clone());
|
||||
|
||||
println!("Request: {}", &incoming_message);
|
||||
|
||||
|
||||
/*command behaviour*/
|
||||
match command {
|
||||
Commands::Connect(Some(params)) => todo!(),
|
||||
_ => todo!(),
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use crate::server::client::client_profile::Client;
|
||||
/*use crate::server::client::client_profile::Client;
|
||||
|
||||
use std::sync::Mutex;
|
||||
use std::sync::Arc;
|
||||
|
|
@ -26,4 +26,4 @@ pub fn get_client_data(clients_ref: &Arc<Mutex<HashMap<String, Client>>>, data:
|
|||
},
|
||||
None => String::from("client not online"),
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use crate::server::client::client_profile::Client;
|
||||
/*use crate::server::client::client_profile::Client;
|
||||
|
||||
pub fn format_client_data(uuid: &String, client: &Client) -> String{
|
||||
["!client: username:",client.get_username(), " uuid:", uuid, " host:\"", client.get_address(), "\""].concat()
|
||||
}
|
||||
}*/
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use crate::server::client::client_profile::Client;
|
||||
/*use crate::server::client::client_profile::Client;
|
||||
|
||||
use std::sync::Mutex;
|
||||
use std::sync::Arc;
|
||||
|
|
@ -10,3 +10,4 @@ pub fn add_client(clients_ref: &Arc<Mutex<HashMap<String, Client>>>, client: &Cl
|
|||
let uuid = client.get_uuid().to_string();
|
||||
//clients_hashmap.insert(uuid, client.clone());
|
||||
}
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use crate::server::client::client_profile::Client;
|
||||
/*use crate::server::client::client_profile::Client;
|
||||
|
||||
use std::sync::Mutex;
|
||||
use std::sync::Arc;
|
||||
|
|
@ -7,4 +7,4 @@ use std::collections::HashMap;
|
|||
pub fn remove_client(clients_ref: &Arc<Mutex<HashMap<String, Client>>>, client: &Client){
|
||||
let mut clients_hashmap = clients_ref.lock().unwrap();
|
||||
clients_hashmap.remove(client.get_uuid()).unwrap();
|
||||
}
|
||||
}*/
|
||||
|
|
|
|||
|
|
@ -10,14 +10,7 @@ mod client;
|
|||
mod test;
|
||||
mod message;
|
||||
|
||||
use crate::server::client::client_profile::Client;
|
||||
use crate::server::server_profile::Server;
|
||||
|
||||
use std::string::ToString;
|
||||
|
||||
use parking_lot::FairMutex;
|
||||
use std::sync::Mutex;
|
||||
use std::sync::Arc;
|
||||
use std::collections::HashMap;
|
||||
use dashmap::DashMap;
|
||||
use std::borrow::Borrow;
|
||||
|
|
@ -136,11 +129,13 @@ impl ToString for Commands {
|
|||
let mut out_string = String::new();
|
||||
|
||||
let (command, parameters) = match self {
|
||||
Commands::Request(arguments) => { ("!request:", arguments) },
|
||||
Commands::Info(arguments) => { ("!info:", arguments) },
|
||||
Commands::Connect(arguments) => { ("!connect:", arguments) },
|
||||
Commands::Disconnect(arguments) => { ("!disconnect:", arguments) },
|
||||
Commands::ClientUpdate(arguments) => { ("!clientUpdate:", arguments) },
|
||||
Commands::ClientInfo(arguments) => { ("!clientInfo:", arguments) },
|
||||
Commands::Client(arguments) => { ("!client:", arguments) },
|
||||
Commands::Error(arguments) => { ("!error:", arguments) },
|
||||
_ => { ("!error:", &None) }
|
||||
};
|
||||
|
|
@ -236,4 +231,4 @@ mod test_commands_v2 {
|
|||
|
||||
println!("{:?}", command.to_string())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,41 +4,40 @@ use crate::server::client::client_profile::Client;
|
|||
use crate::server::commands::{Commands};
|
||||
|
||||
use rust_chat_server::ThreadPool;
|
||||
use std::collections::VecDeque;
|
||||
use std::net::{TcpStream, TcpListener};
|
||||
use std::sync::{Arc, Barrier, Mutex };
|
||||
use crossbeam_channel::{unbounded, Sender, Receiver};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use crossbeam_channel::Sender;
|
||||
use parking_lot::FairMutex;
|
||||
use std::collections::HashMap;
|
||||
use dashmap::DashMap;
|
||||
use std::io::prelude::*;
|
||||
use regex::Regex;
|
||||
|
||||
pub struct Server<'server_lifetime> {
|
||||
name: String,
|
||||
address: String,
|
||||
author: String,
|
||||
connected_clients: Arc<Mutex<HashMap<String,&'server_lifetime Client<'server_lifetime>>>>,
|
||||
pub struct Server<'z> {
|
||||
name: &'z str,
|
||||
address: &'z str,
|
||||
author: &'z str,
|
||||
connected_clients: Arc<Mutex<HashMap<String, Sender<Commands>>>>,
|
||||
thread_pool: ThreadPool,
|
||||
}
|
||||
|
||||
// MARK: - server implemetation
|
||||
impl<'server_lifetime> Server<'server_lifetime> {
|
||||
pub fn new(name: &String, address: &String, author: &String) -> Server<'server_lifetime> {
|
||||
Server{
|
||||
name: name.to_string(),
|
||||
address: address.to_string(),
|
||||
author: author.to_string(),
|
||||
impl<'z> Server<'z> {
|
||||
pub fn new(name: &'z str, address: &'z str, author: &'z str) -> Self {
|
||||
Self {
|
||||
name: name,
|
||||
address: address,
|
||||
author: author,
|
||||
connected_clients: Arc::new(Mutex::new(HashMap::new())),
|
||||
thread_pool: ThreadPool::new(16)
|
||||
thread_pool: ThreadPool::new(16),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_address(&self) -> &String{
|
||||
&self.address
|
||||
|
||||
pub fn get_address(&self) -> String{
|
||||
self.address.to_string()
|
||||
}
|
||||
|
||||
pub fn start(&'server_lifetime self) {
|
||||
pub fn start(&'static self) {
|
||||
let listener = TcpListener::bind(self.get_address()).unwrap();
|
||||
let mut buffer = [0; 1024];
|
||||
|
||||
|
|
@ -47,8 +46,8 @@ impl<'server_lifetime> Server<'server_lifetime> {
|
|||
println!("Server: new connection, {}", addr);
|
||||
|
||||
let request = Commands::Request(None);
|
||||
request.to_string();
|
||||
self.transmit_data(&stream, &*request.to_string().as_str());
|
||||
//request.to_string();
|
||||
self.transmit_data(&stream, &request.to_string().as_str());
|
||||
|
||||
stream.read(&mut buffer).unwrap();
|
||||
|
||||
|
|
@ -64,22 +63,22 @@ impl<'server_lifetime> Server<'server_lifetime> {
|
|||
let mut client = Client::new(self, stream, &uuid, &username, &address);
|
||||
|
||||
let mut clients_hashmap = self.connected_clients.lock().unwrap();
|
||||
|
||||
clients_hashmap.insert(uuid.to_string(), &client);
|
||||
|
||||
clients_hashmap.insert(uuid.to_string(), client.get_transmitter().clone());
|
||||
std::mem::drop(clients_hashmap);
|
||||
|
||||
self.thread_pool.execute(move || {
|
||||
client.handle_connection();
|
||||
});
|
||||
|
||||
let params: HashMap<String, String> = [(String::from("name"), username.clone()), (String::from("host"), address.clone()), (String::from("uuid"), uuid.clone())];
|
||||
let params: HashMap<String, String> = [(String::from("name"), username.clone()), (String::from("host"), address.clone()), (String::from("uuid"), uuid.clone())].iter().cloned().collect();
|
||||
let new_client = Commands::Client(Some(params));
|
||||
|
||||
self.update_all_clients(new_client);
|
||||
},
|
||||
Commands::Info(None) => {
|
||||
let mut params: HashMap<String, String> = HashMap::new();
|
||||
params.insert(String::from("name"), self.name.clone());
|
||||
params.insert(String::from("owner"), self.author.clone());
|
||||
params.insert(String::from("name"), self.name.to_string().clone());
|
||||
params.insert(String::from("owner"), self.author.to_string().clone());
|
||||
|
||||
let command = Commands::Info(Some(params));
|
||||
|
||||
|
|
@ -90,14 +89,14 @@ impl<'server_lifetime> Server<'server_lifetime> {
|
|||
self.transmit_data(&stream, Commands::Error(None).to_string().as_str());
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_info(&self, tx: Sender<Commands>) {
|
||||
let mut params: HashMap<String, String> = HashMap::new();
|
||||
params.insert(String::from("name"), self.name.clone());
|
||||
params.insert(String::from("owner"), self.author.clone());
|
||||
params.insert(String::from("name"), self.name.to_string().clone());
|
||||
params.insert(String::from("owner"), self.author.to_string().clone());
|
||||
|
||||
let command = Commands::Info(Some(params));
|
||||
tx.send(command).unwrap();
|
||||
|
|
@ -105,8 +104,7 @@ impl<'server_lifetime> Server<'server_lifetime> {
|
|||
|
||||
pub fn update_all_clients(&self, command: Commands){
|
||||
let clients = self.connected_clients.lock().unwrap();
|
||||
for client in clients.values(){
|
||||
let tx = client.get_transmitter();
|
||||
for tx in clients.values(){
|
||||
tx.send(command.clone()).unwrap();
|
||||
}
|
||||
}
|
||||
|
|
@ -115,6 +113,11 @@ impl<'server_lifetime> Server<'server_lifetime> {
|
|||
println!("Transmitting...");
|
||||
println!("data: {}",data);
|
||||
|
||||
/*
|
||||
* This will throw an error and crash any thread, including the main thread, if
|
||||
* the connection is lost before transmitting. Maybe change to handle any exceptions
|
||||
* that may occur.
|
||||
*/
|
||||
stream.write(data.to_string().as_bytes()).unwrap();
|
||||
stream.flush().unwrap();
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue