initial message routing capabilities

This commit is contained in:
Emma Tebibyte 2023-06-18 15:56:39 -06:00
parent 410c0d5068
commit a86e1d7af7
Signed by untrusted user: emma
GPG Key ID: 6D661C738815E7DD

View File

@ -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<String>,
}
fn handle_client(stream: TcpStream) {
let mut reader = BufReader::new(&stream);
let mut writer = &stream;
fn handle_client(
client: usize,
clients: Arc<Mutex<HashMap<usize, TcpStream>>>
) {
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<Mutex<HashMap<usize, TcpStream>>> = 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);
}
}
}