use std::io; use std::sync::LazyLock; use tokio::net::UdpSocket; use tokio::sync::Mutex; use super::SERVER_ADDR; pub(crate) static UDP_SERVER: LazyLock> = LazyLock::new(|| Mutex::new(UdpServer::new())); pub(crate) struct UdpServer { is_running: bool, } impl UdpServer { fn new() -> Self { Self { is_running: false } } pub(crate) async fn start(&mut self) { if self.is_running { log::warn!("UDP server is already running"); return; } match UdpSocket::bind(SERVER_ADDR).await { Ok(socket) => { self.is_running = true; tokio::spawn(async move { Self::handle_client(&socket) .await .unwrap_or_else(|e| log::error!("Failed to process data: {e}")) }); log::info!("UDP Server started on {}", SERVER_ADDR); } Err(e) => log::error!("Failed to bind to address: {e}"), } } pub(crate) async fn stop(&mut self) { if !self.is_running { return; } self.is_running = false; } async fn handle_client(socket: &UdpSocket) -> io::Result<()> { loop { let mut buffer = [0; 1024]; let (len, addr) = socket.recv_from(&mut buffer).await?; if len == 0 { break; } log::info!("Received message from client {addr}"); // TODO: Deserialize data let buffer = &buffer[..len]; socket.send_to(buffer, addr).await?; } Ok(()) } }