fixed lifetime and naming issues

This commit is contained in:
michael-bailey 2020-07-16 22:16:16 +01:00
parent 8b78352cc5
commit 226bea4623
4 changed files with 106 additions and 100 deletions

View File

@ -1,10 +1,10 @@
extern crate regex;
use crate::server::commands::{ClientCommands, ServerCommands, Commands};
use crate::server::server_profile::Server;
use crate::server::commands::{Commands};
use std::net::{Shutdown, TcpStream};
use std::sync::{Arc, Mutex};
use std::sync::Arc;
use crossbeam_channel::{Receiver, TryRecvError, unbounded, Sender};
use parking_lot::FairMutex;
use std::collections::HashMap;
@ -25,16 +25,17 @@ pub struct Client<'client_lifetime>{
rx_channel: Receiver<Commands>,
}
impl <'a>Client{
pub fn <'a>new(server: &Server, stream: Arc<TcpStream>, uuid: &String, username: &String, address: &String) -> Client<'a>{
impl<'a> Client<'a> {
pub fn new(server: &'a Server<'a>, stream: Arc<TcpStream>, uuid: &String, username: &String, address: &String) -> Client<'a>{
let (tx_channel, rx_channel): (Sender<Commands>, Receiver<Commands>) = unbounded();
Client{
Client {
connected: true,
stream: stream,
uuid: uuid.to_string(),
username: username.to_string(),
address: address.to_string(),
server: server,
tx_channel: tx_channel,
rx_channel: rx_channel,
}
@ -65,13 +66,17 @@ impl <'a>Client{
let mut buffer = [0; 1024];
while self.connected {
match self.rx_channel.try_recv(){
match self.rx_channel.try_recv() {
/*command is on the channel*/
Ok(command) => {
match command{
let a = command.clone();
match command {
Commands::Info(Some(params)) => {
self.get_stream().write_all(command.to_string);
self.get_stream().write_all(a.to_string().as_bytes());
},
Commands::Disconnect(None) => {
@ -92,22 +97,14 @@ impl <'a>Client{
Ok(_) => {
self.get_stream().read(&mut buffer).unwrap();
let incoming_message = String::from_utf8_lossy(&buffer[..]);
let command = server.tokenize(&incoming_message);
let incoming_message = String::from(String::from_utf8_lossy(&buffer));
let command = Commands::from(incoming_message.clone());
println!("Request: {}", incoming_message);
println!("Request: {}", &incoming_message);
match command{
Ok(cmd) => {
match cmd{
ClientCommands::Connect(_) => println!("Error!"),
_ => {
println!("command executing...");
cmd.execute(self, server, &mut buffer, clients_ref);
},
}
},
Err(e) => println!("{}", e),
match command {
Commands::Connect(Some(params)) => todo!(),
_ => todo!(),
}
},
Err(_) => {
@ -118,6 +115,8 @@ impl <'a>Client{
println!("---thread exit---");
}
// deprecated
/*
pub fn connect(&self, server: &Server, connected_clients: &Arc<Mutex<HashMap<String, Client>>>, data: &HashMap<String, String>){
let mut clients_hashmap = connected_clients.lock().unwrap();
let uuid = self.get_uuid().to_string();
@ -129,6 +128,7 @@ impl <'a>Client{
self.transmit_success(&String::from(""));
}
*/
pub fn disconnect(&mut self){
self.stream.shutdown(Shutdown::Both).expect("shutdown call failed");
@ -143,10 +143,11 @@ impl <'a>Client{
self.get_stream().flush().unwrap();
}
// deprecated
pub fn confirm_success(&self, buffer: &mut [u8; 1024], data: &String){
let success_regex = Regex::new(r###"!success:"###).unwrap();
let _ = match self.get_stream().read(&mut *buffer).unwrap() {
let _ = match self.get_stream().read(&mut *buffer) {
Err(error) => self.transmit_error(&String::from("")),
Ok(success) => {
let incoming_message = String::from_utf8_lossy(&buffer[..]);

View File

@ -8,5 +8,5 @@ use dashmap::DashMap;
pub fn add_client(clients_ref: &Arc<Mutex<HashMap<String, Client>>>, client: &Client){
let mut clients_hashmap = clients_ref.lock().unwrap();
let uuid = client.get_uuid().to_string();
clients_hashmap.insert(uuid, client.clone());
//clients_hashmap.insert(uuid, client.clone());
}

View File

@ -13,29 +13,20 @@ 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;
use regex::Regex;
use std::ops::Index;
#[derive(Clone)]
pub enum ClientCommands{
Info,
Connect(HashMap<String, String>),
Disconnect,
ClientUpdate,
ClientInfo(HashMap<String, String>),
Unknown,
}
#[derive(Clone)]
pub enum ServerCommands{
Client(HashMap<String, String>),
ClientRemove(HashMap<String, String>),
Unknown,
}
/*
impl ClientCommands{
pub fn execute(&self, client: &mut Client, server: &Server, buffer: &mut [u8; 1024], connected_clients: &Arc<Mutex<HashMap<String, Client>>>){
let stream = client.get_stream();
@ -119,9 +110,10 @@ impl ServerCommands{
}
}
}
*/
// MARK: - commands_v2 electric boogaloo
#[derive(Clone)]
pub enum Commands {
Request(Option<HashMap<String, String>>),
Info(Option<HashMap<String, String>>),
@ -138,9 +130,9 @@ pub enum Commands {
Error(Option<HashMap<String, String>>),
}
impl Commands {
pub fn to_String(&self) -> String {
impl ToString for Commands {
fn to_string(&self) -> std::string::String {
let mut out_string = String::new();
let (command, parameters) = match self {
@ -167,8 +159,10 @@ impl Commands {
out_string
}
}
pub fn from_string(data: &str) -> Result<Commands, &'static str> {
impl From<&str> for Commands {
fn from(data: &str) -> Self {
let regex = Regex::new(r###"(\?|!)([a-zA-z0-9]*):|([a-zA-z]*):([a-zA-Z0-9\-\+\[\]{}_=/]+|("(.*?)")+)"###).unwrap();
let mut iter = regex.find_iter(data);
let command = iter.next().unwrap().as_str();
@ -187,27 +181,39 @@ impl Commands {
let params = if map.capacity() > 1 {Some(map)} else { None };
match command {
"!info:" => Ok(Commands::Info(params)),
"!connect:" => Ok(Commands::Connect(params)),
"!clientInfo:" => Ok(Commands::ClientInfo(params)),
"!clientUpdate:" => Ok(Commands::ClientUpdate(params)),
"!disconnect:" => Ok(Commands::Disconnect(params)),
"!error:" => Ok(Commands::Error(params)),
_ => { Err("NOT IMPLEMENTED") }
"!request:" => Commands::Request(params),
"!info:" => Commands::Info(params),
"!connect:" => Commands::Connect(params),
"!disconnect:" => Commands::Disconnect(params),
"!clientUpdate:" => Commands::ClientUpdate(params),
"!clientInfo:" => Commands::ClientInfo(params),
"!client:" => Commands::Client(params),
"!clientRemove:" => Commands::ClientRemove(params),
"!success:" => Commands::Success(params),
"!error:" => Commands::Error(params),
_ => Commands::Error(params),
}
}
}
impl From<String> for Commands {
fn from(data: String) -> Self {
Commands::from(data.as_str())
}
}
#[cfg(test)]
mod test_commands_v2 {
use crate::server_v2::commands_v2::Commands;
use super::Commands;
use std::collections::HashMap;
#[test]
fn test_creation_from_string() {
let command_result = Commands::from_string("!connect: name:bop host:127.0.0.1 uuid:123456-1234-1234-123456");
assert!(command_result.is_ok(), true);
let command = command_result.unwrap_or(Commands::Error(None));
let command_result = Commands::from("!connect: name:bop host:127.0.0.1 uuid:123456-1234-1234-123456");
()
}
@ -221,6 +227,6 @@ mod test_commands_v2 {
let command = Commands::Connect(Some(a));
println!("{:?}", command.to_String())
println!("{:?}", command.to_string())
}
}

View File

@ -1,7 +1,7 @@
extern crate regex;
use crate::server::client::client_profile::Client;
use crate::server::commands::{ClientCommands, ServerCommands, Commands};
use crate::server::commands::{Commands};
use rust_chat_server::ThreadPool;
use std::collections::VecDeque;
@ -23,8 +23,8 @@ pub struct Server<'server_lifetime> {
}
// MARK: - server implemetation
impl Server{
pub fn new<'server_lifetime>(name: &String, address: &String, author: &String) -> Server<'server_lifetime>{
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(),
@ -38,7 +38,7 @@ impl Server{
&self.address
}
pub fn start(&self) {
pub fn start(&'server_lifetime self) {
let listener = TcpListener::bind(self.get_address()).unwrap();
let mut buffer = [0; 1024];
@ -48,48 +48,43 @@ impl Server{
println!("Connected: {}", addr);
let request = Commands::Request(None);
self.transmit_data(&stream, request.to_string().as_str());
request.to_string();
self.transmit_data(&stream, "");
stream.read(&mut buffer).unwrap();
let incoming_message = String::from_utf8_lossy(&buffer[..]);
let result = Commands::from_string(incoming_message.as_str());
match result{
Ok(command) => {
match command{
Commands::Connect(Some(data)) => {
let uuid = data.get("uuid").unwrap();
let username = data.get("name").unwrap();
let address = data.get("host").unwrap();
let incoming_message = String::from(String::from_utf8_lossy(&buffer));
let command = Commands::from(incoming_message);
match command {
Commands::Connect(Some(data)) => {
let uuid = data.get("uuid").unwrap();
let username = data.get("name").unwrap();
let address = data.get("host").unwrap();
let stream = Arc::clone(&stream);
let mut client = Client::new(self, stream, &uuid, &username, &address);
self.thread_pool.execute(move || {
client.handle_connection();
});
let stream = Arc::new(stream);
let mut client = Client::new(self, stream, &uuid, &username, &address);
/*
self.thread_pool.execute(move || {
client.handle_connection();
});
*/
let mut clients_hashmap = self.connected_clients.lock().unwrap();
clients_hashmap.insert(uuid, client.clone());
},
Commands::Info(None) => {
let params: HashMap<String, String> = HashMap::new();
params.insert("name", &self.name);
params.insert("owner", &self.owner);
let command = Commands::Info(Some(params));
self.transmit_data(&stream, command.to_string().as_str());
},
_ => {
println!("Invalid command!");
self.transmit_data(&stream, Commands::Error(None).to_string.as_str());
},
}
let mut clients_hashmap = self.connected_clients.lock().unwrap();
clients_hashmap.insert(uuid.to_string(), client.clone());
},
Err(e) => {
println!("error: {:?}", e);
self.transmit_data(&stream, Commands::Error(None).to_string.as_str());
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());
let command = Commands::Info(Some(params));
self.transmit_data(&stream, command.to_string().as_str());
},
_ => {
println!("Invalid command!");
self.transmit_data(&stream, Commands::Error(None).to_string().as_str());
},
}
}
@ -97,19 +92,19 @@ impl Server{
}
pub fn get_info(&self, tx: Sender<Commands>) {
let params: HashMap<String, String> = HashMap::new();
params.insert("name", &self.name);
params.insert("owner", &self.owner);
let mut params: HashMap<String, String> = HashMap::new();
params.insert(String::from("name"), self.name.clone());
params.insert(String::from("owner"), self.author.clone());
let command = Commands::Info(Some(params));
tx.send(command).unwrap();
}
pub fn update_all_clients(&self, notification: &ServerCommands){
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();
tx.send(notification.clone()).unwrap();
tx.send(command.clone()).unwrap();
}
}
@ -121,6 +116,8 @@ impl Server{
stream.flush().unwrap();
}
//deprecated
/*
pub fn tokenize(&self, incoming_message: &str) -> Result<ClientCommands, &'static str>{
let command_regex = Regex::new(r###"(\?|!)([a-zA-z0-9]*):|([a-zA-z]*):([a-zA-Z0-9\-\+\[\]{}_=/]+|("(.*?)")+)"###).unwrap();
@ -146,6 +143,7 @@ impl Server{
}
}
fn match_command(&self, command: &String) -> ClientCommands{
match command{
_ if command.starts_with("!info:") => ClientCommands::Info,
@ -156,6 +154,7 @@ impl Server{
_ => ClientCommands::Unknown,
}
}
*/
fn regex_data(&self, command_regex: &Regex, data: &str, command_addons: &mut HashMap<String, String>){
for figure in command_regex.find_iter(data){