85 lines
2.8 KiB
Rust
85 lines
2.8 KiB
Rust
use color_eyre::Report;
|
|
use tokio::{
|
|
io::{AsyncBufReadExt, AsyncWriteExt, BufReader},
|
|
net::TcpListener,
|
|
sync::broadcast,
|
|
};
|
|
use tracing::info;
|
|
use tracing_subscriber::filter::EnvFilter;
|
|
|
|
#[tokio::main]
|
|
async fn main() -> Result<(), Report> {
|
|
// Setup the Environment
|
|
setup()?;
|
|
// Set up a TCP listener 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 receiving 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();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
fn setup() -> Result<(), Report> {
|
|
info!("Changing some environment variables!");
|
|
|
|
if std::env::var("RUST_LIB_BACKTRACE").is_err() {
|
|
std::env::set_var("RUST_LIB_BACKTRACE", "1");
|
|
info!("RUST_LIB_BACKTRACE is set. There will be pretty error messages !")
|
|
}
|
|
color_eyre::install()?;
|
|
|
|
if std::env::var("RUST_LOG").is_err() {
|
|
std::env::set_var("RUST_LOG", "info");
|
|
info!("RUST_LOG is set. All errors shall be logged !")
|
|
}
|
|
|
|
tracing_subscriber::fmt::fmt()
|
|
.with_env_filter(EnvFilter::from_default_env())
|
|
.init();
|
|
|
|
Ok(())
|
|
}
|