NetcodeServer

Struct NetcodeServer 

Source
pub struct NetcodeServer { /* private fields */ }
Expand description

A server that can generate packets from connect clients, that are encrypted, or process incoming encrypted packets from clients. The server is agnostic from the transport layer, only consuming and generating bytes that can be transported in any way desired.

Implementations§

Source§

impl NetcodeServer

Source

pub fn new(config: ServerConfig) -> Self

Examples found in repository?
examples/echo.rs (line 130)
121fn server(addr: SocketAddr, private_key: [u8; NETCODE_KEY_BYTES]) {
122    let current_time = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
123    let config = ServerConfig {
124        current_time,
125        max_clients: 16,
126        protocol_id: PROTOCOL_ID,
127        public_addresses: vec![addr],
128        authentication: ServerAuthentication::Secure { private_key },
129    };
130    let mut server: NetcodeServer = NetcodeServer::new(config);
131    let udp_socket = UdpSocket::bind(addr).unwrap();
132    udp_socket.set_nonblocking(true).unwrap();
133    let mut received_messages = vec![];
134    let mut last_updated = Instant::now();
135    let mut buffer = [0u8; NETCODE_MAX_PACKET_BYTES];
136    let mut usernames: HashMap<u64, String> = HashMap::new();
137    loop {
138        server.update(Instant::now() - last_updated);
139        received_messages.clear();
140
141        loop {
142            match udp_socket.recv_from(&mut buffer) {
143                Ok((len, addr)) => {
144                    // println!("Received decrypted message {:?} from {}.", &buffer[..len], addr);
145                    let server_result = server.process_packet(addr, &mut buffer[..len]);
146                    handle_server_result(server_result, &udp_socket, &mut received_messages, &mut usernames);
147                }
148                Err(ref e) if e.kind() == std::io::ErrorKind::WouldBlock => break,
149                Err(e) => panic!("Socket error: {}", e),
150            };
151        }
152
153        for text in received_messages.iter() {
154            for client_id in server.clients_id().iter() {
155                let (addr, payload) = server.generate_payload_packet(*client_id, text.as_bytes()).unwrap();
156                udp_socket.send_to(payload, addr).unwrap();
157            }
158        }
159
160        for client_id in server.clients_id().into_iter() {
161            let server_result = server.update_client(client_id);
162            handle_server_result(server_result, &udp_socket, &mut received_messages, &mut usernames);
163        }
164
165        last_updated = Instant::now();
166        thread::sleep(Duration::from_millis(50));
167    }
168}
Source

pub fn addresses(&self) -> Vec<SocketAddr>

Source

pub fn current_time(&self) -> Duration

Source

pub fn user_data(&self, client_id: u64) -> Option<[u8; 256]>

Returns the user data from the connected client.

Source

pub fn time_since_last_received_packet( &self, client_id: u64, ) -> Option<Duration>

Returns the duration since the connected client last received a packet. Usefull to detect users that are timing out.

Source

pub fn client_addr(&self, client_id: u64) -> Option<SocketAddr>

Returns the client address if connected.

Source

pub fn generate_payload_packet<'s>( &'s mut self, client_id: u64, payload: &[u8], ) -> Result<(SocketAddr, &'s mut [u8]), NetcodeError>

Returns an encoded packet payload to be sent to the client

Examples found in repository?
examples/echo.rs (line 155)
121fn server(addr: SocketAddr, private_key: [u8; NETCODE_KEY_BYTES]) {
122    let current_time = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
123    let config = ServerConfig {
124        current_time,
125        max_clients: 16,
126        protocol_id: PROTOCOL_ID,
127        public_addresses: vec![addr],
128        authentication: ServerAuthentication::Secure { private_key },
129    };
130    let mut server: NetcodeServer = NetcodeServer::new(config);
131    let udp_socket = UdpSocket::bind(addr).unwrap();
132    udp_socket.set_nonblocking(true).unwrap();
133    let mut received_messages = vec![];
134    let mut last_updated = Instant::now();
135    let mut buffer = [0u8; NETCODE_MAX_PACKET_BYTES];
136    let mut usernames: HashMap<u64, String> = HashMap::new();
137    loop {
138        server.update(Instant::now() - last_updated);
139        received_messages.clear();
140
141        loop {
142            match udp_socket.recv_from(&mut buffer) {
143                Ok((len, addr)) => {
144                    // println!("Received decrypted message {:?} from {}.", &buffer[..len], addr);
145                    let server_result = server.process_packet(addr, &mut buffer[..len]);
146                    handle_server_result(server_result, &udp_socket, &mut received_messages, &mut usernames);
147                }
148                Err(ref e) if e.kind() == std::io::ErrorKind::WouldBlock => break,
149                Err(e) => panic!("Socket error: {}", e),
150            };
151        }
152
153        for text in received_messages.iter() {
154            for client_id in server.clients_id().iter() {
155                let (addr, payload) = server.generate_payload_packet(*client_id, text.as_bytes()).unwrap();
156                udp_socket.send_to(payload, addr).unwrap();
157            }
158        }
159
160        for client_id in server.clients_id().into_iter() {
161            let server_result = server.update_client(client_id);
162            handle_server_result(server_result, &udp_socket, &mut received_messages, &mut usernames);
163        }
164
165        last_updated = Instant::now();
166        thread::sleep(Duration::from_millis(50));
167    }
168}
Source

pub fn process_packet<'a, 's>( &'s mut self, addr: SocketAddr, buffer: &'a mut [u8], ) -> ServerResult<'a, 's>

Process an packet from the especifed address. Returns a server result, check out ServerResult.

Examples found in repository?
examples/echo.rs (line 145)
121fn server(addr: SocketAddr, private_key: [u8; NETCODE_KEY_BYTES]) {
122    let current_time = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
123    let config = ServerConfig {
124        current_time,
125        max_clients: 16,
126        protocol_id: PROTOCOL_ID,
127        public_addresses: vec![addr],
128        authentication: ServerAuthentication::Secure { private_key },
129    };
130    let mut server: NetcodeServer = NetcodeServer::new(config);
131    let udp_socket = UdpSocket::bind(addr).unwrap();
132    udp_socket.set_nonblocking(true).unwrap();
133    let mut received_messages = vec![];
134    let mut last_updated = Instant::now();
135    let mut buffer = [0u8; NETCODE_MAX_PACKET_BYTES];
136    let mut usernames: HashMap<u64, String> = HashMap::new();
137    loop {
138        server.update(Instant::now() - last_updated);
139        received_messages.clear();
140
141        loop {
142            match udp_socket.recv_from(&mut buffer) {
143                Ok((len, addr)) => {
144                    // println!("Received decrypted message {:?} from {}.", &buffer[..len], addr);
145                    let server_result = server.process_packet(addr, &mut buffer[..len]);
146                    handle_server_result(server_result, &udp_socket, &mut received_messages, &mut usernames);
147                }
148                Err(ref e) if e.kind() == std::io::ErrorKind::WouldBlock => break,
149                Err(e) => panic!("Socket error: {}", e),
150            };
151        }
152
153        for text in received_messages.iter() {
154            for client_id in server.clients_id().iter() {
155                let (addr, payload) = server.generate_payload_packet(*client_id, text.as_bytes()).unwrap();
156                udp_socket.send_to(payload, addr).unwrap();
157            }
158        }
159
160        for client_id in server.clients_id().into_iter() {
161            let server_result = server.update_client(client_id);
162            handle_server_result(server_result, &udp_socket, &mut received_messages, &mut usernames);
163        }
164
165        last_updated = Instant::now();
166        thread::sleep(Duration::from_millis(50));
167    }
168}
Source

pub fn clients_slot(&self) -> Vec<usize>

Source

pub fn clients_id_iter(&self) -> impl Iterator<Item = u64> + '_

Returns the ids from the connected clients (iterator).

Source

pub fn clients_id(&self) -> Vec<u64>

Returns the ids from the connected clients.

Examples found in repository?
examples/echo.rs (line 154)
121fn server(addr: SocketAddr, private_key: [u8; NETCODE_KEY_BYTES]) {
122    let current_time = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
123    let config = ServerConfig {
124        current_time,
125        max_clients: 16,
126        protocol_id: PROTOCOL_ID,
127        public_addresses: vec![addr],
128        authentication: ServerAuthentication::Secure { private_key },
129    };
130    let mut server: NetcodeServer = NetcodeServer::new(config);
131    let udp_socket = UdpSocket::bind(addr).unwrap();
132    udp_socket.set_nonblocking(true).unwrap();
133    let mut received_messages = vec![];
134    let mut last_updated = Instant::now();
135    let mut buffer = [0u8; NETCODE_MAX_PACKET_BYTES];
136    let mut usernames: HashMap<u64, String> = HashMap::new();
137    loop {
138        server.update(Instant::now() - last_updated);
139        received_messages.clear();
140
141        loop {
142            match udp_socket.recv_from(&mut buffer) {
143                Ok((len, addr)) => {
144                    // println!("Received decrypted message {:?} from {}.", &buffer[..len], addr);
145                    let server_result = server.process_packet(addr, &mut buffer[..len]);
146                    handle_server_result(server_result, &udp_socket, &mut received_messages, &mut usernames);
147                }
148                Err(ref e) if e.kind() == std::io::ErrorKind::WouldBlock => break,
149                Err(e) => panic!("Socket error: {}", e),
150            };
151        }
152
153        for text in received_messages.iter() {
154            for client_id in server.clients_id().iter() {
155                let (addr, payload) = server.generate_payload_packet(*client_id, text.as_bytes()).unwrap();
156                udp_socket.send_to(payload, addr).unwrap();
157            }
158        }
159
160        for client_id in server.clients_id().into_iter() {
161            let server_result = server.update_client(client_id);
162            handle_server_result(server_result, &udp_socket, &mut received_messages, &mut usernames);
163        }
164
165        last_updated = Instant::now();
166        thread::sleep(Duration::from_millis(50));
167    }
168}
Source

pub fn max_clients(&self) -> usize

Returns the maximum number of clients that can be connected.

Source

pub fn set_max_clients(&mut self, max_clients: usize)

Update the maximum numbers of clients that can be connected

Changing the max_clients to a lower value than the current number of connect clients does not disconnect clients. So NetcodeServer::connected_clients() can return a higher value than NetcodeServer::max_clients().

Source

pub fn connected_clients(&self) -> usize

Returns current number of clients connected.

Source

pub fn update(&mut self, duration: Duration)

Advance the server current time, and remove any pending connections that have expired.

Examples found in repository?
examples/echo.rs (line 138)
121fn server(addr: SocketAddr, private_key: [u8; NETCODE_KEY_BYTES]) {
122    let current_time = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
123    let config = ServerConfig {
124        current_time,
125        max_clients: 16,
126        protocol_id: PROTOCOL_ID,
127        public_addresses: vec![addr],
128        authentication: ServerAuthentication::Secure { private_key },
129    };
130    let mut server: NetcodeServer = NetcodeServer::new(config);
131    let udp_socket = UdpSocket::bind(addr).unwrap();
132    udp_socket.set_nonblocking(true).unwrap();
133    let mut received_messages = vec![];
134    let mut last_updated = Instant::now();
135    let mut buffer = [0u8; NETCODE_MAX_PACKET_BYTES];
136    let mut usernames: HashMap<u64, String> = HashMap::new();
137    loop {
138        server.update(Instant::now() - last_updated);
139        received_messages.clear();
140
141        loop {
142            match udp_socket.recv_from(&mut buffer) {
143                Ok((len, addr)) => {
144                    // println!("Received decrypted message {:?} from {}.", &buffer[..len], addr);
145                    let server_result = server.process_packet(addr, &mut buffer[..len]);
146                    handle_server_result(server_result, &udp_socket, &mut received_messages, &mut usernames);
147                }
148                Err(ref e) if e.kind() == std::io::ErrorKind::WouldBlock => break,
149                Err(e) => panic!("Socket error: {}", e),
150            };
151        }
152
153        for text in received_messages.iter() {
154            for client_id in server.clients_id().iter() {
155                let (addr, payload) = server.generate_payload_packet(*client_id, text.as_bytes()).unwrap();
156                udp_socket.send_to(payload, addr).unwrap();
157            }
158        }
159
160        for client_id in server.clients_id().into_iter() {
161            let server_result = server.update_client(client_id);
162            handle_server_result(server_result, &udp_socket, &mut received_messages, &mut usernames);
163        }
164
165        last_updated = Instant::now();
166        thread::sleep(Duration::from_millis(50));
167    }
168}
Source

pub fn update_client(&mut self, client_id: u64) -> ServerResult<'_, '_>

Updates the client, returns a ServerResult.

§Example
for client_id in server.clients_id().into_iter() {
    match server.update_client(client_id) {
        ServerResult::PacketToSend { payload, addr } => send_to(payload, addr),
        _ => { /* ... */ }
    }
}
Examples found in repository?
examples/echo.rs (line 161)
121fn server(addr: SocketAddr, private_key: [u8; NETCODE_KEY_BYTES]) {
122    let current_time = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
123    let config = ServerConfig {
124        current_time,
125        max_clients: 16,
126        protocol_id: PROTOCOL_ID,
127        public_addresses: vec![addr],
128        authentication: ServerAuthentication::Secure { private_key },
129    };
130    let mut server: NetcodeServer = NetcodeServer::new(config);
131    let udp_socket = UdpSocket::bind(addr).unwrap();
132    udp_socket.set_nonblocking(true).unwrap();
133    let mut received_messages = vec![];
134    let mut last_updated = Instant::now();
135    let mut buffer = [0u8; NETCODE_MAX_PACKET_BYTES];
136    let mut usernames: HashMap<u64, String> = HashMap::new();
137    loop {
138        server.update(Instant::now() - last_updated);
139        received_messages.clear();
140
141        loop {
142            match udp_socket.recv_from(&mut buffer) {
143                Ok((len, addr)) => {
144                    // println!("Received decrypted message {:?} from {}.", &buffer[..len], addr);
145                    let server_result = server.process_packet(addr, &mut buffer[..len]);
146                    handle_server_result(server_result, &udp_socket, &mut received_messages, &mut usernames);
147                }
148                Err(ref e) if e.kind() == std::io::ErrorKind::WouldBlock => break,
149                Err(e) => panic!("Socket error: {}", e),
150            };
151        }
152
153        for text in received_messages.iter() {
154            for client_id in server.clients_id().iter() {
155                let (addr, payload) = server.generate_payload_packet(*client_id, text.as_bytes()).unwrap();
156                udp_socket.send_to(payload, addr).unwrap();
157            }
158        }
159
160        for client_id in server.clients_id().into_iter() {
161            let server_result = server.update_client(client_id);
162            handle_server_result(server_result, &udp_socket, &mut received_messages, &mut usernames);
163        }
164
165        last_updated = Instant::now();
166        thread::sleep(Duration::from_millis(50));
167    }
168}
Source

pub fn is_client_connected(&self, client_id: u64) -> bool

Source

pub fn disconnect(&mut self, client_id: u64) -> ServerResult<'_, '_>

Disconnect an client and returns its address and a disconnect packet to be sent to them.

Trait Implementations§

Source§

impl Debug for NetcodeServer

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.