diff --git a/src/main.rs b/src/main.rs index 80a26ad..02e97c8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -17,8 +17,10 @@ */ use std::{ - io::{ self, BufRead, BufReader, Write }, + collections::HashMap, + io::{ BufRead, BufReader, Write }, net::{ TcpListener, TcpStream }, + sync::{ Arc, Mutex }, thread, }; @@ -27,9 +29,13 @@ struct Message { body: Option, } -fn handle_client(stream: TcpStream) { - let mut reader = BufReader::new(&stream); - let mut writer = &stream; +fn handle_client( + client: usize, + clients: Arc>> +) { + let mut reader = BufReader::new( + clients.lock().unwrap().get(&client).unwrap().try_clone().unwrap() + ); let mut message = Message { from: None, @@ -39,11 +45,13 @@ fn handle_client(stream: TcpStream) { loop { let mut send = false; let mut buffer = String::new(); + if reader.read_line(&mut buffer).is_err() { println!( "{} disconnected.", message.from.unwrap_or_else(|| { format!("anon") }), ); + clients.lock().unwrap().remove(&client); break; } @@ -64,6 +72,32 @@ fn handle_client(stream: TcpStream) { } if send { + let mut write_from = String::new(); + if message.from.is_some() { + write_from = format!( + "FROM {}\n", message.from.clone().unwrap() + ); + } + + for (id, mut stream) in clients + .clone() + .lock() + .unwrap() + .drain() { + + if id == client { continue } + + if let Err(err) = stream.write_all( + format!( + "{}BODY {}\n", + write_from, + message.body.clone().unwrap() + ).as_bytes() + ) { + eprintln!("{}: {}", id, err); + } + } + println!( "{}: {}", message.from.clone().unwrap_or_else(|| { format!("anon") }), @@ -78,13 +112,19 @@ fn main() { .expect("Failed to bind to port 8080."); println!("Server listening on port 8080."); - for stream in listener.incoming() { + let connections: Arc>> = Arc::new( + Mutex::new(HashMap::new()) + ); + + for (id, stream) in listener.incoming().enumerate() { match stream { Ok(stream) => { - thread::spawn(move || handle_client(stream)); + let clients = connections.clone(); + clients.lock().unwrap().insert(id.clone(), stream); + thread::spawn(move || handle_client(id, clients)); } - Err(e) => { - eprintln!("Error accepting client connection: {}", e); + Err(err) => { + eprintln!("Error accepting client connection: {}", err); } } }