69 lines
1.6 KiB
Rust
69 lines
1.6 KiB
Rust
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<Mutex<UdpServer>> =
|
|
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(())
|
|
}
|
|
}
|