68 lines
1.8 KiB
Rust
68 lines
1.8 KiB
Rust
mod conf;
|
|
|
|
use std::sync::Arc;
|
|
|
|
use conf::Configuration;
|
|
use tokio::{net::UdpSocket, sync::mpsc};
|
|
|
|
const BUFFER_SIZE: usize = 1024;
|
|
|
|
struct RawDatagram {
|
|
len: usize,
|
|
data: [u8; BUFFER_SIZE],
|
|
}
|
|
|
|
#[tokio::main]
|
|
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|
// Load and check configuration
|
|
let configuration: Configuration = confy::load("chat-server")?;
|
|
configuration.check()?;
|
|
|
|
// Start listening for user datagrams
|
|
let socket = UdpSocket::bind((configuration.ip, configuration.port)).await?;
|
|
let socket = Arc::new(socket);
|
|
|
|
let (dgram_parse_tx, dgram_parse_rx) = mpsc::channel::<RawDatagram>(1024);
|
|
|
|
// Run a listen thread.
|
|
{
|
|
let socket = socket.clone();
|
|
tokio::spawn(async move {
|
|
let mut buf = [0; BUFFER_SIZE]; // Receive at most 1024 bytes (remaining is truncated)
|
|
loop {
|
|
let recv = socket.recv_from(&mut buf).await;
|
|
if recv.is_err() {
|
|
// Something went wrong with the socket, it's possible that the connection
|
|
// was closed.
|
|
break;
|
|
}
|
|
let (len, _) = recv.unwrap();
|
|
|
|
// Read a datagram from the socket; send for parsing.
|
|
let raw_datagram = RawDatagram { len, data: buf.clone() };
|
|
if dgram_parse_tx.send(raw_datagram).await.is_err() {
|
|
// The channel has been closed.
|
|
break;
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
// Run a parsing thread.
|
|
{
|
|
let mut dgram_parse_rx = dgram_parse_rx;
|
|
loop {
|
|
let recv = dgram_parse_rx.recv().await;
|
|
if recv.is_none() {
|
|
// The channel has been closed.
|
|
break;
|
|
}
|
|
let recv = recv.unwrap();
|
|
|
|
|
|
}
|
|
}
|
|
|
|
Ok(())
|
|
}
|