### Build and Run WASM App with npm Source: https://github.com/ukoehb/renet2/blob/main/examples/echo_client_wasm/README.md This snippet demonstrates the command-line steps to build the WASM application using wasm-pack, install npm dependencies, and start the development server. It requires wasm-pack and npm to be installed beforehand. ```bash wasm-pack build && cd wasm-app && npm install && npm run start ``` -------------------------------- ### Bevy Renet Client Setup and Usage (Rust) Source: https://github.com/ukoehb/renet2/blob/main/bevy_renet2/README.md This code illustrates the setup for a Bevy client using RenetClientPlugin and NetcodeClientPlugin. It configures the RenetClient and NetcodeClientTransport resources, including client authentication. Systems for sending and receiving messages are provided. Ensure the SERVER_ADDR and protocol_id are correctly set. ```rust let mut app = App::new(); app.add_plugin(RenetClientPlugin); let client = RenetClient::new(ConnectionConfig::default()); app.insert_resource(client); // Setup the transport layer app.add_plugin(NetcodeClientPlugin); let authentication = ClientAuthentication::Unsecure { server_addr: SERVER_ADDR, client_id: 0, user_data: None, protocol_id: 0, socket_id: 0, }; let socket = UdpSocket::bind("127.0.0.1:0").unwrap(); let current_time = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap(); let mut transport = NetcodeClientTransport::new(current_time, authentication, NativeSocket::new(socket).unwrap()).unwrap(); app.insert_resource(transport); app.add_system(send_message_system); app.add_system(receive_message_system); // Systems fn send_message_system(mut client: ResMut) { // Send a text message to the server client.send_message(DefaultChannel::ReliableOrdered, "server message"); } fn receive_message_system(mut client: ResMut) { while let Some(message) = client.receive_message(DefaultChannel::ReliableOrdered) { // Handle received message } } ``` -------------------------------- ### Renet2 Server Setup and Network Loop in Rust Source: https://github.com/ukoehb/renet2/blob/main/README.md This snippet demonstrates how to initialize and run a Renet2 server. It includes setting up the transport layer with UDP sockets, defining server configuration, and managing the main loop for receiving and sending messages. It also shows how to handle client connection and disconnection events, and broadcast messages to connected clients. ```rust let mut server = RenetServer::new(ConnectionConfig::default()); // Setup transport layer const SERVER_ADDR: SocketAddr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 5000); let socket: UdpSocket = UdpSocket::bind(SERVER_ADDR).unwrap(); let server_config = ServerConfig { current_time: SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap(), max_clients: 64, protocol_id: 0, public_addresses: vec![SERVER_ADDR], authentication: ServerAuthentication::Unsecure }; let mut transport = NetcodeServerTransport::new(server_config, socket).unwrap(); // Your gameplay loop loop { let delta_time = Duration::from_millis(16); // Receive new messages and update clients server.update(delta_time); transport.update(delta_time, &mut server)?; // Check for client connections/disconnections while let Some(event) = server.get_event() { match event { ServerEvent::ClientConnected { client_id } => { println!("Client {client_id} connected"); } ServerEvent::ClientDisconnected { client_id, reason } => { println!("Client {client_id} disconnected: {reason}"); } } } // Receive message from channel for client_id in server.clients_id() { // The enum DefaultChannel describe the channels used by the default configuration while let Some(message) = server.receive_message(client_id, DefaultChannel::ReliableOrdered) { // Handle received message } } // Send a text message for all clients server.broadcast_message(DefaultChannel::ReliableOrdered, "server message"); let client_id = 0; // Send a text message for all clients except for Client 0 server.broadcast_message_except(client_id, DefaultChannel::ReliableOrdered, "server message"); // Send message to only one client server.send_message(client_id, DefaultChannel::ReliableOrdered, "server message"); // Send packets to clients using the transport layer transport.send_packets(&mut server); std::thread::sleep(delta_time); // Running at 60hz } ``` -------------------------------- ### Bevy Renet Server Setup and Usage (Rust) Source: https://github.com/ukoehb/renet2/blob/main/bevy_renet2/README.md This code demonstrates how to set up a Bevy server using the RenetServerPlugin and NetcodeServerPlugin. It initializes the RenetServer and NetcodeServerTransport resources, and includes systems for sending and receiving messages, as well as handling client connection/disconnection events. Dependencies include `bevy_renet2` and potentially `renet2`'s transport layer. ```rust let mut app = App::new(); app.add_plugin(RenetServerPlugin); let server = RenetServer::new(ConnectionConfig::default()); app.insert_resource(server); // Transport layer setup app.add_plugin(NetcodeServerPlugin); let server_addr = "127.0.0.1:5000".parse().unwrap(); let socket = UdpSocket::bind(server_addr).unwrap(); let server_config = ServerSetupConfig { current_time: SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap(), max_clients: 64, protocol_id: 0, socket_addresses: vec![vec![server_addr]], authentication: ServerAuthentication::Unsecure }; let transport = NetcodeServerTransport::new(server_config, NativeSocket::new(socket).unwrap()).unwrap(); app.insert_resource(transport); app.add_system(send_message_system); app.add_system(receive_message_system); app.add_system(handle_events_system); // Systems fn send_message_system(mut server: ResMut) { let channel_id = 0; // Send a text message for all clients // The enum DefaultChannel describe the channels used by the default configuration server.broadcast_message(DefaultChannel::ReliableOrdered, "server message"); } fn receive_message_system(mut server: ResMut) { // Receive message from all clients for client_id in server.clients_id() { while let Some(message) = server.receive_message(client_id, DefaultChannel::ReliableOrdered) { // Handle received message } } } fn handle_events_system(mut server_events: EventReader) { for event in server_events.read() { match event { ServerEvent::ClientConnected { client_id } => { println!("Client {client_id} connected"); } ServerEvent::ClientDisconnected { client_id, reason } => { println!("Client {client_id} disconnected: {reason}"); } } } } ``` -------------------------------- ### Channel Configuration Example (Rust) Source: https://github.com/ukoehb/renet2/blob/main/README.md Defines a `ChannelConfig` for Renet, specifying the channel ID, maximum memory usage, and the configured `SendType`. This allows customization of how messages are transmitted over a specific channel. ```rust let channel_config = ChannelConfig { // The id for the channel, must be unique within its own list, // but it can be repeated between the server and client lists. channel_id: 0, // Maximum number of bytes that the channel may hold without acknowledgement of messages before becoming full. max_memory_usage_bytes: 5 * 1024 * 1024, // 5 mebibytes send_type }; ``` -------------------------------- ### Local Client-Server Testing in Rust with Renet2 Source: https://context7.com/ukoehb/renet2/llms.txt This Rust code snippet illustrates how to establish a local client-server connection for testing with Renet2. It initializes a server and a local client, processes updates and messages between them in a loop, and demonstrates sending and receiving reliable ordered messages. This setup is useful for debugging and testing network logic without external connections. ```rust use renet2::{RenetServer, RenetClient, ConnectionConfig, DefaultChannel}; use std::time::Duration; let mut server = RenetServer::new(ConnectionConfig::test()); // Create a local client connected directly to the server let client_id = 1; let mut local_client = server.new_local_client(client_id); // Main update loop loop { let delta = Duration::from_millis(16); // Update both server.update(delta); local_client.update(delta); // Process packets between client and server server.process_local_client(client_id, &mut local_client).unwrap(); // Client sends message local_client.send_message(DefaultChannel::ReliableOrdered, b"test".to_vec()); // Server receives message while let Some(msg) = server.receive_message(client_id, DefaultChannel::ReliableOrdered) { println!("Server received: {:?}", msg); } // Server sends response server.send_message(client_id, DefaultChannel::ReliableOrdered, b"response".to_vec()); // Client receives response while let Some(msg) = local_client.receive_message(DefaultChannel::ReliableOrdered) { println!("Client received: {:?}", msg); } std::thread::sleep(delta); } // Disconnect local client server.disconnect_local_client(client_id, &mut local_client); ``` -------------------------------- ### Renet2 Client Setup and Network Loop in Rust Source: https://github.com/ukoehb/renet2/blob/main/README.md This snippet illustrates how to initialize and manage a Renet2 client. It covers setting up the transport layer with UDP sockets and client authentication. The code demonstrates the main loop for updating the client, sending and receiving messages to/from the server, and checking the connection status. It also shows how to send packets to the server via the transport layer. ```rust let mut client = RenetClient::new(ConnectionConfig::default(), false); // Setup transport layer const server_addr: SocketAddr = "127.0.0.1:5000".parse().unwrap(); let socket = UdpSocket::bind("127.0.0.1:0").unwrap(); let current_time = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap(); let authentication = ClientAuthentication::Unsecure { server_addr, client_id: 0, user_data: None, protocol_id: 0, }; let mut transport = NetcodeClientTransport::new(current_time, authentication, socket).unwrap(); // Your gameplay loop loop { let delta_time = Duration::from_millis(16); // Receive new messages and update client client.update(delta_time); transport.update(delta_time, &mut client).unwrap(); if client.is_connected() { // Receive message from server while let Some(message) = client.receive_message(DefaultChannel::ReliableOrdered) { // Handle received message } // Send message client.send_message(DefaultChannel::ReliableOrdered, "client text"); } // Send packets to server using the transport layer transport.send_packets(&mut client)?; std::thread::sleep(delta_time); // Running at 60hz } ``` -------------------------------- ### Rust Server Setup with UDP Transport Source: https://context7.com/ukoehb/renet2/llms.txt Sets up a Renet2 server using UDP transport for communication. It configures the server, UDP socket, and transport layer, then enters a main loop to update the server, handle client events, and send/receive packets. Dependencies include `renet2`, `renet2_netcode`, and `renetcode2`. ```rust use std::net::{IpAddr, Ipv4Addr, SocketAddr, UdpSocket}; use std::time::{Duration, SystemTime}; use renet2::{ConnectionConfig, RenetServer, ServerEvent, DefaultChannel}; use renet2_netcode::{NetcodeServerTransport, ServerSetupConfig}; use renetcode2::ServerAuthentication; // Create the renet server let mut server = RenetServer::new(ConnectionConfig::test()); // Setup UDP socket const SERVER_ADDR: SocketAddr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 5000); let socket = UdpSocket::bind(SERVER_ADDR).unwrap(); // Configure server transport let current_time = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap(); let server_config = ServerSetupConfig { current_time, max_clients: 64, protocol_id: 0, socket_addresses: vec![vec![SERVER_ADDR]], authentication: ServerAuthentication::Unsecure, }; let mut transport = NetcodeServerTransport::new(server_config, socket).unwrap(); // Main game loop loop { let delta_time = Duration::from_millis(16); // Update server and transport server.update(delta_time); transport.update(delta_time, &mut server).unwrap(); // Handle connection events while let Some(event) = server.get_event() { match event { ServerEvent::ClientConnected { client_id } => { println!("Client {} connected", client_id); } ServerEvent::ClientDisconnected { client_id, reason } => { println!("Client {} disconnected: {}", client_id, reason); } } } // Send packets to all clients transport.send_packets(&mut server); std::thread::sleep(delta_time); } ``` -------------------------------- ### Renet Server with Steam Transport Setup Source: https://github.com/ukoehb/renet2/blob/main/renet2_steam/README.md Configures and initializes a Renet server with the SteamServerTransport. This involves setting up the Steam client, creating a Renet server instance, and then initializing the Steam transport layer with server-specific configurations like maximum clients and access permissions. The loop demonstrates updating Steam callbacks, Renet server, and the Steam transport, along with handling client connection and disconnection events. ```rust use std::time::Duration; use std::thread; use renet2_steam::{SteamServerConfig, SteamServerTransport}; use renet2::{ConnectionConfig, RenetServer, ServerEvent}; use steamworks::{Client, AccessPermission, SteamId}; // Setup steam client let (steam_client, single) = Client::init_app(480).unwrap(); steam_client.networking_utils().init_relay_network_access(); // Create renet server let connection_config = ConnectionConfig::default(); let mut server: RenetServer = RenetServer::new(connection_config); // Create steam transport let access_permission = AccessPermission::Public; let steam_transport_config = SteamServerConfig { max_clients: 10, access_permission, }; let mut steam_transport = SteamServerTransport::new(&steam_client, steam_transport_config).unwrap(); // Your gameplay loop loop { let delta_time = Duration::from_millis(16); single.run_callbacks(); // Update steam callbacks server.update(delta_time); steam_transport.update(&mut server); // Handle connect/disconnect events while let Some(event) = server.get_event() { match event { ServerEvent::ClientConnected { client_id } => { println!("Client {} connected.", client_id) } ServerEvent::ClientDisconnected { client_id, reason } => { println!("Client {} disconnected: {}", client_id, reason); } } } // Code for sending/receiving messages can go here // Check the examples/demos steam_transport.send_packets(&mut server); thread::sleep(delta_time); } ``` -------------------------------- ### Channel SendType Configuration (Rust) Source: https://github.com/ukoehb/renet2/blob/main/README.md Demonstrates the configuration of `SendType` for Renet channels, specifying message delivery guarantees. Includes examples for Unreliable, ReliableOrdered, and ReliableUnordered, along with their respective resend durations. ```rust // No guarantee of message delivery or order let send_type = SendType::Unreliable; // Guarantee of message delivery and order let send_type = SendType::ReliableOrdered { // If a message is lost, it will be resent after this duration resend_time: Duration::from_millis(300) }; // Guarantee of message delivery but not order let send_type = SendType::ReliableUnordered { resend_time: Duration::from_millis(300) }; ``` -------------------------------- ### Renet Client with Steam Transport Setup Source: https://github.com/ukoehb/renet2/blob/main/renet2_steam/README.md Initializes a Renet client and connects it using the SteamClientTransport. This requires setting up the Steam client, creating a Renet client instance, and then establishing the Steam transport connection to a specified server Steam ID. The main loop handles Steam callbacks, Renet client updates, and the Steam transport, including sending outgoing packets. ```rust use std::time::Duration; use std::thread; use renet2_steam::SteamClientTransport; use renet2::{ConnectionConfig, RenetClient}; use steamworks::{Client, SteamId}; // Setup steam client let (steam_client, single) = Client::init_app(480).unwrap(); steam_client.networking_utils().init_relay_network_access(); // Create renet client let connection_config = ConnectionConfig::default(); let mut client = RenetClient::new(connection_config); // Create steam transport let server_steam_id = SteamId::from_raw(0); // Here goes the steam id of the host let mut steam_transport = SteamClientTransport::new(&steam_client, &server_steam_id).unwrap(); // Your gameplay loop loop { let delta_time = Duration::from_millis(16); single.run_callbacks(); // Update steam callbacks client.update(delta_time); steam_transport.update(&mut client); // Code for sending/receiving messages can go here // Check the examples/demos steam_transport.send_packets(&mut client).unwrap(); thread::sleep(delta_time); } ``` -------------------------------- ### Build Workspace Documentation (Rust) Source: https://github.com/ukoehb/renet2/blob/main/README.md Builds the documentation for the entire Rust workspace, excluding dependencies and WASM targets. The `--open` flag automatically opens the generated documentation in a web browser. ```rust cargo doc --open --no-deps --all-features ``` -------------------------------- ### Configure Renet2 Channels with Different Reliability Guarantees (Rust) Source: https://context7.com/ukoehb/renet2/llms.txt Demonstrates how to configure custom network channels in Renet2, including unreliable, reliable ordered, and reliable unordered channels. It shows setting channel IDs, memory usage, and resend times, then creating a `ConnectionConfig` and initializing `RenetServer` and `RenetClient`. ```rust use std::time::Duration; use renet2::{ChannelConfig, SendType, ConnectionConfig, RenetServer, RenetClient}; // Unreliable channel - no delivery guarantees, lowest latency let unreliable_channel = ChannelConfig { channel_id: 0, max_memory_usage_bytes: 5 * 1024 * 1024, // 5 MB send_type: SendType::Unreliable, }; // Reliable ordered channel - guarantees delivery and order let reliable_ordered = ChannelConfig { channel_id: 1, max_memory_usage_bytes: 5 * 1024 * 1024, send_type: SendType::ReliableOrdered { resend_time: Duration::from_millis(300), }, }; // Reliable unordered channel - guarantees delivery but not order let reliable_unordered = ChannelConfig { channel_id: 2, max_memory_usage_bytes: 5 * 1024 * 1024, send_type: SendType::ReliableUnordered { resend_time: Duration::from_millis(300), }, }; // Create connection config with custom channels let config = ConnectionConfig::from_shared_channels(vec![ unreliable_channel, reliable_ordered, reliable_unordered, ]); let mut server = RenetServer::new(config.clone()); let mut client = RenetClient::new(config, false); ``` -------------------------------- ### Renet Client Metrics Visualization (Rust) Source: https://github.com/ukoehb/renet2/blob/main/renet2_visualizer/README.md This Rust code snippet demonstrates how to initialize and use the RenetClientVisualizer to display network metrics on the client-side. It requires the `renet2_visualizer` crate and an `egui_ctx`. The visualizer is updated with client network information and then rendered in an egui window. ```rust let mut visualizer = RenetClientVisualizer::<200>::new(RenetVisualizerStyle::default()); // .. loop { // Update Renet Client client.update(delta).unwrap(); // Add metrics to the visualizer visualizer.add_network_info(client.network_info()); // Draws a new egui window with the metrics visualizer.show_window(egui_ctx); // .. } ``` -------------------------------- ### Renet Server Metrics and Client Management Visualization (Rust) Source: https://github.com/ukoehb/renet2/blob/main/renet2_visualizer/README.md This Rust code snippet illustrates the server-side usage of RenetServerVisualizer for displaying network metrics and managing connected clients. It involves initializing the visualizer, processing server events (client connections/disconnections), updating client metrics, and rendering the information in an egui window. Dependencies include `renet2_visualizer` and an `egui_ctx`. ```rust let mut visualizer = RenetServerVisualizer::<200>::new(RenetVisualizerStyle::default()); // .. loop { // Update Renet Server server.update(delta).unwrap(); // Add/Remove clients from the visualizer while let Some(event) = server.get_event() { match event { ServerEvent::ClientConnected(client_id, user_data) => { visualizer.add_client(client_id); // ... } ServerEvent::ClientDisconnected(client_id) => { visualizer.remove_client(client_id); // ... } } } // Add all clients metrics to the visualizer visualizer.update(&server); // Draws a new egui window with all clients metrics visualizer.show_window(egui_ctx); // .. } ``` -------------------------------- ### Client Disconnection Handling (Rust) Source: https://context7.com/ukoehb/renet2/llms.txt Demonstrates how to manage client disconnections in Renet2. For the client, it shows how to check connection status ('is_connected', 'is_connecting', 'is_disconnected') and retrieve the disconnection reason. For the server, it illustrates how to manually disconnect specific clients or all clients using 'disconnect' and 'disconnect_all' methods. Dependencies include 'renet2'. ```rust use renet2::{RenetClient, RenetConnectionStatus, RenetServer, ConnectionConfig, DefaultChannel}; // Client-side disconnection handling let mut client = RenetClient::new(ConnectionConfig::test(), false); // Check connection status if client.is_connected() { // Client is fully connected and can send/receive client.send_message(DefaultChannel::Unreliable, b"message".to_vec()); } if client.is_connecting() { // Client is still connecting println!("Connecting to server..."); } if client.is_disconnected() { // Client has been disconnected if let Some(reason) = client.disconnect_reason() { println!("Disconnected: {:?}", reason); } } // Manually disconnect client client.disconnect(); // Server-side disconnection handling let mut server = RenetServer::new(ConnectionConfig::test()); let client_id = 42; // Disconnect specific client server.disconnect(client_id); // Disconnect all clients server.disconnect_all(); // Remove connection (called by transport layer) server.remove_connection(client_id); ``` -------------------------------- ### Channel Configuration Source: https://context7.com/ukoehb/renet2/llms.txt Configure custom channels with different reliability guarantees (unreliable, reliable ordered, reliable unordered) and integrate them into the connection configuration. ```APIDOC ## Channel Configuration This section details how to configure custom network channels with varying reliability and ordering guarantees for Renet2. ### Description Allows for the creation of different channel types, such as Unreliable, ReliableOrdered, and ReliableUnordered, each with specific configurations for memory usage and re-send timers. These custom channels can then be used to build a `ConnectionConfig` for both servers and clients. ### Method Instantiation and Configuration ### Endpoint N/A (Client-side configuration) ### Parameters #### Request Body (Conceptual) - **channel_id** (u8) - Required - A unique identifier for the channel. - **max_memory_usage_bytes** (usize) - Required - The maximum memory buffer size for this channel. - **send_type** (SendType) - Required - Specifies the reliability and ordering of the channel. Can be `Unreliable`, `ReliableOrdered { resend_time: Duration }`, or `ReliableUnordered { resend_time: Duration }`. ### Request Example ```rust use std::time::Duration; use renet2::{ChannelConfig, SendType, ConnectionConfig}; // Unreliable channel - no delivery guarantees, lowest latency let unreliable_channel = ChannelConfig { channel_id: 0, max_memory_usage_bytes: 5 * 1024 * 1024, // 5 MB send_type: SendType::Unreliable, }; // Reliable ordered channel - guarantees delivery and order let reliable_ordered = ChannelConfig { channel_id: 1, max_memory_usage_bytes: 5 * 1024 * 1024, send_type: SendType::ReliableOrdered { resend_time: Duration::from_millis(300), }, }; // Reliable unordered channel - guarantees delivery but not order let reliable_unordered = ChannelConfig { channel_id: 2, max_memory_usage_bytes: 5 * 1024 * 1024, send_type: SendType::ReliableUnordered { resend_time: Duration::from_millis(300), }, }; // Create connection config with custom channels let config = ConnectionConfig::from_shared_channels(vec![ unreliable_channel, reliable_ordered, reliable_unordered, ]); ``` ### Response N/A (Configuration is applied locally) ### Response Example N/A ``` -------------------------------- ### Broadcast and Send Targeted Messages with Renet2 Server (Rust) Source: https://context7.com/ukoehb/renet2/llms.txt Illustrates how to manage messages on the server-side using Renet2. This includes broadcasting messages to all clients, sending private messages to specific clients, broadcasting to all except one, and receiving and echoing messages back to clients. ```rust use renet2::{RenetServer, DefaultChannel, ConnectionConfig}; let mut server = RenetServer::new(ConnectionConfig::test()); // Broadcast message to all clients server.broadcast_message(DefaultChannel::ReliableOrdered, b"Server announcement".to_vec()); // Send message to specific client let client_id = 42; server.send_message(client_id, DefaultChannel::ReliableOrdered, b"Private message".to_vec()); // Broadcast to all except one client server.broadcast_message_except(client_id, DefaultChannel::Unreliable, b"Everyone else".to_vec()); // Receive messages from clients for client_id in server.clients_id() { while let Some(message) = server.receive_message(client_id, DefaultChannel::ReliableOrdered) { let text = String::from_utf8(message.into()).unwrap(); println!("Client {}: {}", client_id, text); // Echo back to sender server.send_message(client_id, DefaultChannel::ReliableOrdered, format!("Echo: {}", text)); } } ``` -------------------------------- ### Cross-Platform Server with UDP, WebTransport, and WebSocket (Rust) Source: https://context7.com/ukoehb/renet2/llms.txt Sets up a Renet server that can handle connections from clients using UDP, WebTransport, and WebSocket protocols. It initializes native UDP, WebTransport, and WebSocket sockets, configures them for multi-transport, and runs a server loop that processes events and sends packets transparently across all transports. Dependencies include 'renet2', 'renet2_netcode', 'tokio', and 'renetcode2'. ```rust use std::net::{SocketAddr, UdpSocket}; use std::time::SystemTime; use renet2::{ConnectionConfig, RenetServer, ServerEvent, DefaultChannel}; use renet2_netcode::{ BoxedSocket, NativeSocket, NetcodeServerTransport, ServerSetupConfig, WebTransportServer, WebTransportServerConfig, WebSocketServer, WebSocketServerConfig, }; use renetcode2::ServerAuthentication; let runtime = tokio::runtime::Runtime::new().unwrap(); let max_clients = 10; let wildcard_addr: SocketAddr = "127.0.0.1:0".parse().unwrap(); // Create native UDP socket let native_socket = NativeSocket::new(UdpSocket::bind(wildcard_addr).unwrap()).unwrap(); // Create WebTransport socket (for WASM clients) let (wt_socket, cert_hash) = { let (config, cert_hash) = WebTransportServerConfig::new_selfsigned(wildcard_addr, max_clients).unwrap(); (WebTransportServer::new(config, runtime.handle().clone()).unwrap(), cert_hash) }; // Create WebSocket socket (for WASM clients) let ws_socket = { let config = WebSocketServerConfig::new(wildcard_addr, max_clients); WebSocketServer::new(config, runtime.handle().clone()).unwrap() }; // Setup multi-transport server let current_time = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap(); let server_config = ServerSetupConfig { current_time, max_clients, protocol_id: 0, socket_addresses: vec![ vec![native_socket.addr().unwrap()], vec![wt_socket.addr().unwrap()], vec![ws_socket.addr().unwrap()], ], authentication: ServerAuthentication::Unsecure, }; let mut transport = NetcodeServerTransport::new_with_sockets( server_config, vec![ BoxedSocket::new(native_socket), BoxedSocket::new(wt_socket), BoxedSocket::new(ws_socket), ], ).unwrap(); let mut server = RenetServer::new(ConnectionConfig::test()); // Server loop handles all transport types transparently loop { let duration = std::time::Duration::from_millis(50); transport.update(duration, &mut server).unwrap(); while let Some(event) = server.get_event() { match event { ServerEvent::ClientConnected { client_id } => { server.send_message(client_id, DefaultChannel::Unreliable, b"Welcome!".to_vec()); } ServerEvent::ClientDisconnected { client_id, reason } => { println!("Client {} disconnected: {}", client_id, reason); } } } transport.send_packets(&mut server); std::thread::sleep(duration); } ``` -------------------------------- ### Build WASM Documentation (Rust) Source: https://github.com/ukoehb/renet2/blob/main/README.md Builds documentation for the 'renet2_netcode' workspace crate specifically for WebAssembly targets, excluding default features and enabling specific WebTransport and WebSocket client transport features. This command is executed after changing the directory to 'renet2_netcode'. ```rust cd renet2_netcode &&\ cargo doc --open --no-deps --no-default-features --features=wt_client_transport,ws_client_transport --target wasm32-unknown-unknown ``` -------------------------------- ### Monitor Renet2 Network Statistics and Performance (Rust) Source: https://context7.com/ukoehb/renet2/llms.txt Shows how to access and interpret network performance metrics for connected clients using Renet2. This includes retrieving round-trip time (RTT), packet loss percentage, and bandwidth usage (sent/received bytes per second) both individually and as a consolidated `NetworkInfo` struct. It also demonstrates checking channel capacity before sending a message. ```rust use renet2::{RenetServer, NetworkInfo, ConnectionConfig, DefaultChannel}; let server = RenetServer::new(ConnectionConfig::test()); let client_id = 42; // Get individual metrics let rtt = server.rtt(client_id); // Round-trip time in seconds let packet_loss = server.packet_loss(client_id); // Packet loss percentage let bytes_sent = server.bytes_sent_per_sec(client_id); let bytes_received = server.bytes_received_per_sec(client_id); println!("Client {} - RTT: {:.3}s, Loss: {:.2}%", client_id, rtt, packet_loss * 100.0); println!("Bandwidth - Sent: {:.2} KB/s, Received: {:.2} KB/s", bytes_sent / 1024.0, bytes_received / 1024.0); // Get all network info at once match server.network_info(client_id) { Ok(info) => { println!("Network Info:"); println!(" RTT: {:.3}s", info.rtt); println!(" Packet Loss: {:.2}%", info.packet_loss * 100.0); println!(" Upload: {:.2} KB/s", info.bytes_sent_per_second / 1024.0); println!(" Download: {:.2} KB/s", info.bytes_received_per_second / 1024.0); } Err(_) => println!("Client not found"), } // Check channel capacity before sending if server.can_send_message(client_id, DefaultChannel::ReliableOrdered, 1024) { server.send_message(client_id, DefaultChannel::ReliableOrdered, vec![0u8; 1024]); } else { println!("Channel full, cannot send message"); } ``` -------------------------------- ### Network Statistics Source: https://context7.com/ukoehb/renet2/llms.txt Provides methods to monitor network performance metrics such as round-trip time (RTT), packet loss, and bandwidth usage for individual clients. ```APIDOC ## Network Statistics This section describes how to access and interpret network performance metrics for connected clients in Renet2. ### Description Enables monitoring of critical network parameters like Round-Trip Time (RTT), packet loss rate, and data transfer speeds (sent/received bytes per second). This information is crucial for diagnosing connection issues and optimizing game performance. It also includes a utility to check if a channel has sufficient capacity before attempting to send large messages. ### Method - `rtt(client_id: u64) -> f32` - `packet_loss(client_id: u64) -> f32` - `bytes_sent_per_sec(client_id: u64) -> f32` - `bytes_received_per_sec(client_id: u64) -> f32` - `network_info(client_id: u64) -> Result` - `can_send_message(client_id: u64, channel_id: u8, message_len: usize) -> bool` ### Endpoint N/A (Server-side monitoring) ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Request Example ```rust use renet2::{RenetServer, NetworkInfo, RenetError}; let server = RenetServer::new(ConnectionConfig::test()); let client_id = 42; // Get individual metrics let rtt = server.rtt(client_id); // Round-trip time in seconds let packet_loss = server.packet_loss(client_id); // Packet loss percentage let bytes_sent = server.bytes_sent_per_sec(client_id); let bytes_received = server.bytes_received_per_sec(client_id); println!("Client {} - RTT: {:.3}s, Loss: {:.2}%", client_id, rtt, packet_loss * 100.0); println!("Bandwidth - Sent: {:.2} KB/s, Received: {:.2} KB/s", bytes_sent / 1024.0, bytes_received / 1024.0); // Get all network info at once match server.network_info(client_id) { Ok(info) => { println!("Network Info:"); println!(" RTT: {:.3}s", info.rtt); println!(" Packet Loss: {:.2}%", info.packet_loss * 100.0); println!(" Upload: {:.2} KB/s", info.bytes_sent_per_second / 1024.0); println!(" Download: {:.2} KB/s", info.bytes_received_per_second / 1024.0); } Err(e) => println!("Error retrieving network info for client {}: {}", client_id, e), } // Check channel capacity before sending if server.can_send_message(client_id, DefaultChannel::ReliableOrdered, 1024) { server.send_message(client_id, DefaultChannel::ReliableOrdered, vec![0u8; 1024]); } else { println!("Channel full, cannot send message"); } ``` ### Response #### Success Response (200) - **`rtt`** (f32) - The round-trip time in seconds. - **`packet_loss`** (f32) - The packet loss percentage (0.0 to 1.0). - **`bytes_sent_per_sec`** (f32) - Bytes sent per second. - **`bytes_received_per_sec`** (f32) - Bytes received per second. - **`network_info`** (`NetworkInfo` struct) - Contains `rtt`, `packet_loss`, `bytes_sent_per_second`, and `bytes_received_per_second`. - **`can_send_message`** (bool) - Returns `true` if the specified channel has enough buffer capacity to send a message of the given length, `false` otherwise. #### Response Example ```rust // Example output from printing network stats // Client 42 - RTT: 0.052s, Loss: 0.50% // Bandwidth - Sent: 10.24 KB/s, Received: 5.12 KB/s // Example NetworkInfo struct // Network Info: // RTT: 0.052s // Packet Loss: 0.50% // Upload: 10.24 KB/s // Download: 5.12 KB/s ``` ``` -------------------------------- ### Server Message Broadcasting Source: https://context7.com/ukoehb/renet2/llms.txt Handles broadcasting messages to all clients, sending targeted messages to specific clients, and receiving messages from clients on the server. ```APIDOC ## Server Message Broadcasting This section covers how a Renet2 server can broadcast messages to all connected clients, send messages to individual clients, and process incoming messages. ### Description Provides methods for a server to efficiently distribute data across its client base. This includes sending announcements to everyone, private messages to specific users, and receiving acknowledgments or data from clients. It also demonstrates how to echo messages back to the sender. ### Method - `broadcast_message(channel_id: u8, message: Vec)` - `send_message(client_id: u64, channel_id: u8, message: Vec)` - `broadcast_message_except(client_id_except: u64, channel_id: u8, message: Vec)` - `receive_message(client_id: u64, channel_id: u8) -> Option` ### Endpoint N/A (Server-side operations) ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body (Conceptual) - **client_id** (u64) - Required - The unique identifier of the target client. - **client_id_except** (u64) - Required - The ID of the client to exclude from a broadcast. - **channel_id** (u8) - Required - The ID of the channel to send the message on. - **message** (Vec) - Required - The byte payload of the message to send. ### Request Example ```rust use renet2::{RenetServer, DefaultChannel}; let mut server = RenetServer::new(ConnectionConfig::test()); // Broadcast message to all clients server.broadcast_message(DefaultChannel::ReliableOrdered, b"Server announcement".to_vec()); // Send message to specific client let client_id = 42; server.send_message(client_id, DefaultChannel::ReliableOrdered, b"Private message".to_vec()); // Broadcast to all except one client server.broadcast_message_except(client_id, DefaultChannel::Unreliable, b"Everyone else".to_vec()); // Receive messages from clients for client_id in server.clients_id() { while let Some(message) = server.receive_message(client_id, DefaultChannel::ReliableOrdered) { let text = String::from_utf8(message.into()).unwrap(); println!("Client {}: {}", client_id, text); // Echo back to sender server.send_message(client_id, DefaultChannel::ReliableOrdered, format!("Echo: {}", text)); } } ``` ### Response #### Success Response (200) - **Received Message** (`Option`): When `receive_message` is called, returns `Some(message)` if a message is available on the specified channel for the client, otherwise `None`. #### Response Example ```rust // Example of processing a received message if let Some(message) = server.receive_message(client_id, DefaultChannel::ReliableOrdered) { let text = String::from_utf8(message.into()).unwrap(); println!("Received: {}", text); } ``` ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.