diff --git a/Server/src/network_service/tcp_server.rs b/Server/src/network_service/tcp_server.rs index e9e1f7d..dab0fc7 100644 --- a/Server/src/network_service/tcp_server.rs +++ b/Server/src/network_service/tcp_server.rs @@ -1,5 +1,6 @@ -use tokio::io::{ErrorKind, Interest}; +use tokio::io::{self, ErrorKind, Interest}; use tokio::net::{TcpListener, TcpStream}; +use tokio::time::{self, Duration}; pub(crate) struct TcpServer; @@ -11,7 +12,33 @@ impl TcpServer { Ok((socket, addr)) => { log::info!("New client connected: {addr}"); - tokio::spawn(async { Self::process(socket).await }); + tokio::spawn(async move { + let mut retry_times = 0; + + while retry_times <= 3 { + let result = Self::process(&socket).await; + + match result { + Ok(_) => continue, + Err(e) if e.kind() == ErrorKind::WouldBlock => continue, + Err(e) => { + if retry_times == 3 { + log::error!("Failed to process this socket: {e}"); + + return; + } + + retry_times += 1; + + log::error!( + "Failed to process this socket: {e}. Retry {retry_times} time(s)..." + ); + + time::sleep(Duration::from_secs(1)).await; + } + } + } + }); } Err(e) => log::error!("Couldn't get client: {e:?}"), } @@ -20,44 +47,26 @@ impl TcpServer { } } - async fn process(socket: TcpStream) { - loop { - match socket.ready(Interest::READABLE | Interest::WRITABLE).await { - Ok(ready) => { - if ready.is_readable() { - let mut buffer = Vec::with_capacity(1024); - match socket.try_read_buf(&mut buffer) { - // We need to write to client after reading from that, - // so we use `continue` here instead if `break`. - Ok(_) => { - log::info!("Received contents"); + async fn process(socket: &TcpStream) -> io::Result<()> { + let ready = socket + .ready(Interest::READABLE | Interest::WRITABLE) + .await?; + if ready.is_readable() { + // Size of per received data shound be smaller than 1KiB. + let mut buffer = [0; 1024]; + let size = socket.try_read(&mut buffer)?; - // TODO: Start dispatching messages here. + log::info!("Received {size} Bytes message.") - continue; - } - Err(e) if e.kind() == ErrorKind::WouldBlock => continue, - Err(e) => { - log::error!("Failed to read from TCP client socket: {e}"); - - break; - } - } - } - if ready.is_writable() { - match socket.try_write(b"Hello from server written in Rust!") { - Ok(_) => continue, - Err(e) if e.kind() == ErrorKind::WouldBlock => continue, - Err(e) => { - log::error!("Failed to write to TCP client socket: {e}"); - - break; - } - } - } - } - Err(e) => log::error!("Failed to wait for any states: {e}"), - } + // TODO: Start dispatching messages here. } + if ready.is_writable() { + // TODO: Start sending back message here. + let size = socket.try_write(b"Hello from server written in Rust!")?; + + log::info!("Sent {size} Bytes message.") + } + + Ok(()) } }