Skip to main content

sharded_echo/
sharded_echo.rs

1//! Echo server using a fixed Linux receive-socket group.
2#[cfg(target_os = "linux")]
3#[tokio::main]
4async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
5    use rust_raknet::{RaknetListener, Reliability};
6    let address = std::env::args().nth(1).ok_or("ADDRESS required")?.parse()?;
7    let count = std::env::args()
8        .nth(2)
9        .unwrap_or_else(|| "4".into())
10        .parse()?;
11    let mut listener = RaknetListener::bind_with_socket_shards(&address, count).await?;
12    let mut batch_messages = false;
13    for option in std::env::args().skip(3) {
14        listener = match option.as_str() {
15            "--receive-batching" => listener.with_receive_batching(true),
16            "--idle-maintenance" => listener.with_idle_maintenance(true),
17            "--batch-messages" => {
18                batch_messages = true;
19                listener
20            }
21            _ => return Err(format!("unknown option: {option}").into()),
22        };
23    }
24    listener.listen().await;
25    println!("Sharded echo listening on {}", listener.local_addr()?);
26    loop {
27        let client = listener.accept().await?;
28        if batch_messages {
29            tokio::spawn(async move {
30                let mut messages = Vec::with_capacity(16);
31                while client.recv_bytes_batch(&mut messages, 16).await.is_ok() {
32                    if client
33                        .send_bytes_batch(&messages, Reliability::ReliableOrdered)
34                        .await
35                        .is_err()
36                    {
37                        break;
38                    }
39                    if messages.len() == 16 {
40                        tokio::task::yield_now().await;
41                    }
42                }
43            });
44        } else {
45            tokio::spawn(async move {
46                while let Ok(payload) = client.recv().await {
47                    if client
48                        .send(&payload, Reliability::ReliableOrdered)
49                        .await
50                        .is_err()
51                    {
52                        break;
53                    }
54                }
55            });
56        }
57    }
58}
59
60#[cfg(not(target_os = "linux"))]
61fn main() {
62    eprintln!("Socket sharding requires Linux");
63}