pub struct RaknetListener { /* private fields */ }Expand description
A RakNet UDP server that accepts incoming connections.
Implementations§
Source§impl RaknetListener
impl RaknetListener
Sourcepub async fn bind(sockaddr: &SocketAddr) -> Result<Self>
pub async fn bind(sockaddr: &SocketAddr) -> Result<Self>
Bind a RakNet listener to the specified UDP address.
Call listen before accepting connections.
Sourcepub async fn bind_with_maximum_mtu(
sockaddr: &SocketAddr,
maximum_mtu: u16,
) -> Result<Self>
pub async fn bind_with_maximum_mtu( sockaddr: &SocketAddr, maximum_mtu: u16, ) -> Result<Self>
Bind a listener with an explicit maximum nominal MTU in bytes.
The maximum must be between 61 and 1,492 bytes. Offline negotiation chooses the smaller of this limit and the client’s request. Ordinary listeners retain their 1,400-byte maximum.
Sourcepub async fn bind_with_socket_shards(
sockaddr: &SocketAddr,
count: NonZeroUsize,
) -> Result<Self>
pub async fn bind_with_socket_shards( sockaddr: &SocketAddr, count: NonZeroUsize, ) -> Result<Self>
Bind a fixed group of UDP receive sockets on Linux.
All shards use the same address, server GUID, MOTD and accept backlog.
Linux SO_REUSEPORT distributes peer flows across the fixed group. Create
every shard before listening and retain the group for the listener’s lifetime.
The count must be at most 64; one shard uses the ordinary binding path.
This changes only these sockets and does not alter system network limits.
Examples found in repository?
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}Sourcepub async fn bind_with_receive_buffer_size(
sockaddr: &SocketAddr,
size: NonZeroUsize,
) -> Result<Self>
pub async fn bind_with_receive_buffer_size( sockaddr: &SocketAddr, size: NonZeroUsize, ) -> Result<Self>
Sourcepub fn with_accept_backlog(self, backlog: NonZeroUsize) -> Self
pub fn with_accept_backlog(self, backlog: NonZeroUsize) -> Self
Sourcepub fn with_idle_maintenance(self, enabled: bool) -> Self
pub fn with_idle_maintenance(self, enabled: bool) -> Self
Enable idle maintenance for newly accepted connections on every shard.
Disabled by default. See RaknetSocket::set_idle_maintenance for the
CPU savings and scheduling tradeoff. Configure before listening.
§Panics
Panics if called after listen.
Examples found in repository?
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}Sourcepub fn with_receive_batching(self, enabled: bool) -> Self
pub fn with_receive_batching(self, enabled: bool) -> Self
Enable Linux recvmmsg batches of up to 16 ready datagrams.
Disabled by default: this can improve busy listeners’ throughput but costs extra work for sparse traffic. No timer waits to fill a batch. The setting applies to every receive socket in a sharded listener.
§Panics
Panics if called after listen.
Examples found in repository?
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}Sourcepub async fn from_std(socket: UdpSocket) -> Result<Self>
pub async fn from_std(socket: UdpSocket) -> Result<Self>
Creates a listener from a standard UDP socket.
Sourcepub async fn listen(&mut self)
pub async fn listen(&mut self)
Start receiving connection requests.
Call this before accept. Repeated calls have no effect.
Examples found in repository?
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}Sourcepub async fn accept(&mut self) -> Result<RaknetSocket>
pub async fn accept(&mut self) -> Result<RaknetSocket>
Wait for and accept the next incoming RakNet connection.
Call listen first.
§Example
let mut listener = RaknetListener::bind("127.0.0.1:19132".parse().unwrap()).await.unwrap();
listener.listen().await;
let mut socket = listener.accept().await.unwrap();Examples found in repository?
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}Sourcepub fn get_guid(&self) -> u64
pub fn get_guid(&self) -> u64
Get the GUID, a random number that uniquely identifies the listener instance.
Sourcepub async fn set_motd(
&mut self,
server_name: &str,
max_connection: u32,
mc_protocol_version: &str,
mc_version: &str,
game_type: &str,
port: u16,
) -> Result<()>
pub async fn set_motd( &mut self, server_name: &str, max_connection: u32, mc_protocol_version: &str, mc_version: &str, game_type: &str, port: u16, ) -> Result<()>
Sourcepub fn local_addr(&self) -> Result<SocketAddr>
pub fn local_addr(&self) -> Result<SocketAddr>
Return the local UDP address used by this listener.
§Example
let mut socket = RaknetListener::bind("127.0.0.1:19132".parse().unwrap()).await.unwrap();
assert_eq!(socket.local_addr().unwrap().ip(), IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)));Examples found in repository?
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}