use tokio::{ io::{AsyncBufReadExt, AsyncWriteExt, BufReader}, net::TcpListener, sync::broadcast, }; #[tokio::main] async fn main() { // Set up a TCP listenner to listen for incoming tcp requests let listener = TcpListener::bind("127.0.0.1:8080").await.unwrap(); // Setting up broadcast channel: A channel that will accept messages and broadcast them to everyone connected to the TCP server // the channel accepts an i32 that is the maximum number of messages the channel can retain at any given time let (sender, _receiver) = broadcast::channel(10); // First loop accept all the tcp client requests loop { // prevent the compiler error when we try to access something in a loop when it was initialized outside of the loop let sender = sender.clone(); let mut receiver = sender.subscribe(); // accept the requests let (mut socket, addr) = listener.accept().await.unwrap(); tokio::spawn(async move { // Splitting the TCP socket into read/write halves let (reader, mut writer) = socket.split(); let mut buffer_reader = BufReader::new(reader); let mut line: String = String::new(); // second loop keeps receving input from that one client going loop { tokio::select! { result = buffer_reader.read_line(&mut line) => { if result.unwrap() == 0{ break; } // send items to the broadcast channel sender.send((line.clone(), addr)).unwrap(); // clear the input buffer line.clear(); } result = receiver.recv() => { let (msg, other_addr) = result.unwrap(); if addr != other_addr { writer.write_all(msg.as_bytes()).await.unwrap(); } } } } }); } }