renet_udp/
server.rs

1use renet::{
2    disconnect_packet,
3    error::{DisconnectionReason, RenetError},
4    remote_connection::ConnectionConfig,
5    server::Server,
6};
7
8use log::error;
9use std::{
10    collections::VecDeque,
11    io,
12    net::{SocketAddr, UdpSocket},
13    time::Duration,
14};
15
16#[derive(Debug)]
17pub struct UdpServer {
18    socket: UdpSocket,
19    server: Server<SocketAddr>,
20    buffer: Box<[u8]>,
21    events: VecDeque<ServerEvent>,
22}
23
24#[derive(Debug, Clone)]
25pub enum ServerEvent {
26    ClientConnected(SocketAddr),
27    ClientDisconnected(SocketAddr, DisconnectionReason),
28}
29
30impl UdpServer {
31    pub fn new(max_clients: usize, connection_config: ConnectionConfig, socket: UdpSocket) -> Result<Self, std::io::Error> {
32        let buffer = vec![0u8; connection_config.max_packet_size as usize].into_boxed_slice();
33        let server = Server::new(max_clients, connection_config);
34        socket.set_nonblocking(true)?;
35
36        Ok(Self {
37            socket,
38            server,
39            buffer,
40            events: VecDeque::new(),
41        })
42    }
43
44    pub fn addr(&self) -> Result<SocketAddr, io::Error> {
45        self.socket.local_addr()
46    }
47
48    pub fn get_event(&mut self) -> Option<ServerEvent> {
49        self.events.pop_front()
50    }
51
52    pub fn disconnect(&mut self, client_id: &SocketAddr) {
53        self.server.disconnect(client_id);
54    }
55
56    pub fn disconnect_clients(&mut self) {
57        self.server.disconnect_all();
58    }
59
60    pub fn update(&mut self, duration: Duration) -> Result<(), io::Error> {
61        loop {
62            match self.socket.recv_from(&mut self.buffer) {
63                Ok((len, addr)) => {
64                    if !self.server.is_connected(&addr) {
65                        match self.server.add_connection(&addr) {
66                            Ok(()) => self.events.push_back(ServerEvent::ClientConnected(addr)),
67                            Err(reason) => self.send_disconnect_packet(&addr, reason),
68                        }
69                    }
70                    if let Err(e) = self.server.process_packet_from(&self.buffer[..len], &addr) {
71                        error!("Error while processing payload for {}: {}", addr, e)
72                    }
73                }
74                Err(ref e) if e.kind() == std::io::ErrorKind::WouldBlock => break,
75                Err(e) => return Err(e),
76            };
77        }
78
79        self.server.update_connections(duration);
80        while let Some((client_id, reason)) = self.server.disconnected_client() {
81            self.events.push_back(ServerEvent::ClientDisconnected(client_id, reason));
82            self.send_disconnect_packet(&client_id, reason);
83        }
84        Ok(())
85    }
86
87    fn send_disconnect_packet(&self, addr: &SocketAddr, reason: DisconnectionReason) {
88        if matches!(reason, DisconnectionReason::DisconnectedByClient) {
89            return;
90        }
91        match disconnect_packet(reason) {
92            Ok(packet) => {
93                const NUM_DISCONNECT_PACKETS_TO_SEND: u32 = 5;
94                for _ in 0..NUM_DISCONNECT_PACKETS_TO_SEND {
95                    if let Err(e) = self.socket.send_to(&packet, addr) {
96                        error!("failed to send disconnect packet to {}: {}", addr, e);
97                    }
98                }
99            }
100            Err(e) => {
101                error!("failed to serialize disconnect packet: {}", e);
102            }
103        }
104    }
105
106    pub fn receive_message(&mut self, client: &SocketAddr, channel_id: u8) -> Option<Vec<u8>> {
107        self.server.receive_message(client, channel_id)
108    }
109
110    pub fn send_message(&mut self, client_id: &SocketAddr, channel_id: u8, message: Vec<u8>) -> Result<(), RenetError> {
111        self.server.send_message(client_id, channel_id, message)
112    }
113
114    pub fn broadcast_message_except(&mut self, client_id: &SocketAddr, channel_id: u8, message: Vec<u8>) {
115        self.server.broadcast_message_except(client_id, channel_id, message)
116    }
117
118    pub fn broadcast_message(&mut self, channel_id: u8, message: Vec<u8>) {
119        self.server.broadcast_message(channel_id, message);
120    }
121
122    pub fn send_packets(&mut self) -> Result<(), io::Error> {
123        for client_id in self.server.connections_id().iter() {
124            let packets = match self.server.get_packets_to_send(client_id) {
125                Ok(p) => p,
126                Err(e) => {
127                    self.server.disconnect(client_id);
128                    error!("Failed to get packets from {}: {}", client_id, e);
129                    continue;
130                }
131            };
132
133            for packet in packets.iter() {
134                self.socket.send_to(packet, client_id)?;
135            }
136        }
137        Ok(())
138    }
139
140    pub fn clients_id(&self) -> Vec<SocketAddr> {
141        self.server.connections_id()
142    }
143}