UDP
UDP uses datagram pipelines. The model is similar to TCP, but the boundary is a complete datagram rather than a byte stream.
Server
UdpServer::bind(addr) creates a socket server builder. .pipeline(|| ...) sets the socket-level pipeline factory:
#![allow(unused)]
fn main() {
use rs_netty::{codec::Utf8DatagramCodec, datagram_pipeline, handler, Result, UdpServer};
struct UdpEcho;
#[handler(UdpEcho)]
async fn udp_echo(msg: String) -> Result<String> {
Ok(format!("echo: {msg}"))
}
let server = UdpServer::bind("127.0.0.1:0")
.pipeline(|| {
datagram_pipeline()
.codec(Utf8DatagramCodec)
.handler(UdpEcho)
})
.start()
.await?;
server.shutdown();
server.wait().await?;
Ok::<(), rs_netty::Error>(())
}
UdpServerHandle exposes local_addr(), shutdown(), and wait().
Client
UdpClient::connect(remote_addr) binds to "0.0.0.0:0" by default. Use .bind(local_addr) to choose a local address. UdpClientHandle<W> provides these methods for the default remote peer:
write(msg)flush()write_and_flush(msg)
It also supports explicit peers:
write_to(peer_addr, msg)write_to_and_flush(peer_addr, msg)
Socket-Level Pipeline
A UDP server currently creates one socket-level pipeline, not a child pipeline per peer. For every datagram, the runtime creates new DatagramInfo, InboundContext, BusinessContext, DatagramContext, and OutboundContext values. peer_addr() is the sender of the current datagram.
If the application needs per-peer state, store it in the handler yourself:
#![allow(unused)]
fn main() {
use std::{collections::HashMap, net::SocketAddr};
struct PeerState;
struct StatefulUdp {
peers: HashMap<SocketAddr, PeerState>,
}
}
Configuration
UDP uses UdpSocketConfig:
read_buffer_capacity: default 64 KiB; normalized to at leastmax_datagram_size.write_buffer_capacity: default 8 KiB.max_datagram_size: default 64 KiB.outbound_queue_size: default 1024.
Builder methods include:
read_buffer_capacity(value)write_buffer_capacity(value)max_datagram_size(value)outbound_queue_size(value)
UDP currently has no TCP-style tcp_nodelay, connection stats, or idle timeout.
Datagram Write Semantics
DatagramContext::write(msg) writes to the current datagram peer. write_to(peer, msg) writes to an explicit peer. Both only stage data in the handler-local outbox. flush or *_and_flush sends pending datagrams through send_to.
A UDP flush acknowledgement only means the local send_to call completed. It does not mean the peer received the datagram, and UDP still provides no ordering, retransmission, or reliability guarantee.