use crate::broadcaster::TcpBroadcaster; use crate::error::TcpServerError; use std::sync::Arc; use tokio::io::AsyncWriteExt; use tokio::net::TcpListener; use tokio::sync::broadcast; use tracing::{info, warn}; pub async fn run_tcp_server( addr: &str, broadcaster: Arc, ) -> Result<(), TcpServerError> { let listener = TcpListener::bind(addr).await.map_err(TcpServerError::Io)?; info!(addr, "TCP server listening"); loop { let (mut socket, peer) = listener.accept().await.map_err(TcpServerError::Io)?; info!(%peer, "client connected"); let mut rx = broadcaster.subscribe(); tokio::spawn(async move { loop { match rx.recv().await { Ok(frame) => { if socket.write_all(&frame).await.is_err() { info!(%peer, "client disconnected"); break; } } Err(broadcast::error::RecvError::Closed) => break, Err(broadcast::error::RecvError::Lagged(n)) => { warn!(%peer, skipped = n, "client lagged"); } } } }); } }