Code Examples

Practical examples to help you get started with WebSocket RS

1. Simple Echo Server

A basic server that echoes back all messages it receives.

src/main.rs
use websocket_rs::{WebSocketServer, Message};

#[tokio::main]
async fn main() -> Result<(), Box> {
    // Create a WebSocket server on localhost:8080
    let mut server = WebSocketServer::new("127.0.0.1:8080");
    
    println!("Echo server running on ws://127.0.0.1:8080");
    println!("Send any message and it will be echoed back!");
    
    // Start the server with echo handler
    server.start(|client_id, message| {
        println!("Received from client {}: {}", client_id, message);
        
        // Echo the message back
        Message::Text(format!("Echo: {}", message))
    }).await?;
    
    Ok(())
}

Test with JavaScript:

JavaScript
const ws = new WebSocket('ws://localhost:8080');

ws.onopen = () => {
    console.log('Connected to echo server');
    ws.send('Hello World!');
};

ws.onmessage = (event) => {
    console.log('Server says:', event.data);
    // Output: "Server says: Echo: Hello World!"
};

2. Chat Server with Rooms

A multi-room chat server where users can join different rooms and broadcast messages.

src/main.rs
use websocket_rs::{WebSocketServer, Message};
use std::collections::HashMap;
use std::sync::{Arc, Mutex};
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize, Debug)]
enum ChatCommand {
    Join { room: String, username: String },
    Leave { room: String },
    Message { room: String, text: String },
}

#[derive(Clone)]
struct ChatServer {
    rooms: Arc>>>,
    users: Arc>>,
}

impl ChatServer {
    fn new() -> Self {
        Self {
            rooms: Arc::new(Mutex::new(HashMap::new())),
            users: Arc::new(Mutex::new(HashMap::new())),
        }
    }
}

#[tokio::main]
async fn main() -> Result<(), Box> {
    let mut server = WebSocketServer::new("127.0.0.1:8080");
    let chat = ChatServer::new();
    
    println!("Chat server running on ws://127.0.0.1:8080");
    
    server.on_message(move |client_id, message| {
        if let Message::Text(text) = message {
            match serde_json::from_str::(&text) {
                Ok(cmd) => match cmd {
                    ChatCommand::Join { room, username } => {
                        // Add user to room
                        let mut rooms = chat.rooms.lock().unwrap();
                        rooms.entry(room.clone())
                            .or_insert_with(Vec::new)
                            .push(client_id);
                        
                        // Store username
                        chat.users.lock().unwrap()
                            .insert(client_id, username.clone());
                        
                        // Notify room
                        let msg = format!("{} joined the room", username);
                        server.broadcast_to_room(&room, msg).await?;
                    },
                    ChatCommand::Message { room, text } => {
                        let users = chat.users.lock().unwrap();
                        let username = users.get(&client_id)
                            .unwrap_or(&"Anonymous".to_string());
                        
                        let msg = format!("{}: {}", username, text);
                        server.broadcast_to_room(&room, msg).await?;
                    },
                    ChatCommand::Leave { room } => {
                        let mut rooms = chat.rooms.lock().unwrap();
                        if let Some(clients) = rooms.get_mut(&room) {
                            clients.retain(|&id| id != client_id);
                        }
                    },
                },
                Err(e) => {
                    eprintln!("Failed to parse command: {}", e);
                }
            }
        }
    });
    
    server.start().await?;
    Ok(())
}

Client Example:

JavaScript
const ws = new WebSocket('ws://localhost:8080');

ws.onopen = () => {
    // Join a room
    ws.send(JSON.stringify({
        Join: { room: 'general', username: 'Alice' }
    }));
    
    // Send a message
    setTimeout(() => {
        ws.send(JSON.stringify({
            Message: { room: 'general', text: 'Hello everyone!' }
        }));
    }, 1000);
};

ws.onmessage = (event) => {
    console.log(event.data);
};

3. Real-time Data Dashboard

Stream live data updates to connected clients for monitoring dashboards.

src/main.rs
use websocket_rs::WebSocketServer;
use serde::{Deserialize, Serialize};
use tokio::time::{interval, Duration};
use rand::Rng;

#[derive(Serialize)]
struct SystemStats {
    timestamp: u64,
    cpu_usage: f32,
    memory_usage: f32,
    active_connections: usize,
}

#[tokio::main]
async fn main() -> Result<(), Box> {
    let server = Arc::new(WebSocketServer::new("127.0.0.1:8080"));
    let server_clone = server.clone();
    
    println!("Dashboard server running on ws://127.0.0.1:8080");
    
    // Spawn a task to broadcast stats every second
    tokio::spawn(async move {
        let mut interval = interval(Duration::from_secs(1));
        let mut rng = rand::thread_rng();
        
        loop {
            interval.tick().await;
            
            let stats = SystemStats {
                timestamp: chrono::Utc::now().timestamp() as u64,
                cpu_usage: rng.gen_range(0.0..100.0),
                memory_usage: rng.gen_range(0.0..100.0),
                active_connections: server_clone.connection_count(),
            };
            
            let json = serde_json::to_string(&stats).unwrap();
            let _ = server_clone.broadcast(json).await;
        }
    });
    
    server.start().await?;
    Ok(())
}

HTML Dashboard:

dashboard.html
<!DOCTYPE html>
<html>
<head>
    <title>System Dashboard</title>
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
</head>
<body>
    <h1>Real-time System Monitor</h1>
    <canvas id="cpuChart"></canvas>
    <canvas id="memoryChart"></canvas>
    
    <script>
        const ws = new WebSocket('ws://localhost:8080');
        const cpuData = [];
        const memoryData = [];
        const labels = [];
        
        // Initialize charts
        const cpuChart = new Chart(document.getElementById('cpuChart'), {
            type: 'line',
            data: {
                labels: labels,
                datasets: [{
                    label: 'CPU Usage %',
                    data: cpuData,
                    borderColor: 'rgb(99, 102, 241)',
                }]
            }
        });
        
        ws.onmessage = (event) => {
            const stats = JSON.parse(event.data);
            
            // Update charts
            labels.push(new Date(stats.timestamp * 1000).toLocaleTimeString());
            cpuData.push(stats.cpu_usage);
            memoryData.push(stats.memory_usage);
            
            // Keep only last 20 data points
            if (labels.length > 20) {
                labels.shift();
                cpuData.shift();
                memoryData.shift();
            }
            
            cpuChart.update();
        };
    </script>
</body>
</html>

4. Push Notification System

Send real-time notifications to connected clients with targeting options.

src/main.rs
use websocket_rs::WebSocketServer;
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize)]
struct Notification {
    id: String,
    title: String,
    message: String,
    priority: String,
    timestamp: i64,
}

#[tokio::main]
async fn main() -> Result<(), Box> {
    let server = WebSocketServer::new("127.0.0.1:8080");
    
    // Example: Send notification to all users
    let notification = Notification {
        id: uuid::Uuid::new_v4().to_string(),
        title: "System Update".to_string(),
        message: "A new version is available".to_string(),
        priority: "high".to_string(),
        timestamp: chrono::Utc::now().timestamp(),
    };
    
    let json = serde_json::to_string(¬ification)?;
    server.broadcast(json).await?;
    
    Ok(())
}

5. Authenticated WebSocket Server

Secure your WebSocket connections with JWT authentication.

src/main.rs
use websocket_rs::WebSocketServer;
use jsonwebtoken::{decode, DecodingKey, Validation};

#[tokio::main]
async fn main() -> Result<(), Box> {
    let mut server = WebSocketServer::new("127.0.0.1:8080");
    
    // Verify token on connection
    server.on_connect(|client_id, request| {
        // Get token from query parameter
        if let Some(token) = request.query("token") {
            // Verify JWT token
            match decode::(
                &token,
                &DecodingKey::from_secret("secret".as_ref()),
                &Validation::default()
            ) {
                Ok(token_data) => {
                    println!("Client {} authenticated as {}", 
                        client_id, token_data.claims.sub);
                    return Ok(());
                },
                Err(e) => {
                    eprintln!("Authentication failed: {}", e);
                }
            }
        }
        
        Err("Unauthorized")
    });
    
    server.start().await?;
    Ok(())
}

Client with Authentication:

JavaScript
const token = 'your-jwt-token-here';
const ws = new WebSocket(`ws://localhost:8080?token=${token}`);

ws.onopen = () => {
    console.log('Authenticated and connected!');
};

ws.onerror = () => {
    console.error('Authentication failed');
};

6. Multiplayer Game Server

Real-time game state synchronization for multiplayer games.

src/main.rs
use websocket_rs::WebSocketServer;
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize)]
struct Player {
    id: usize,
    x: f32,
    y: f32,
    score: u32,
}

#[derive(Serialize, Deserialize)]
enum GameMessage {
    PlayerJoined(Player),
    PlayerMoved { id: usize, x: f32, y: f32 },
    PlayerScored { id: usize, score: u32 },
    GameState(Vec),
}

#[tokio::main]
async fn main() -> Result<(), Box> {
    let server = WebSocketServer::new("127.0.0.1:8080");
    let mut players = HashMap::new();
    
    server.on_message(move |client_id, message| {
        if let Message::Text(text) = message {
            if let Ok(game_msg) = serde_json::from_str::(&text) {
                match game_msg {
                    GameMessage::PlayerMoved { id, x, y } => {
                        // Update player position
                        if let Some(player) = players.get_mut(&id) {
                            player.x = x;
                            player.y = y;
                        }
                        
                        // Broadcast to all players
                        let update = GameMessage::PlayerMoved { id, x, y };
                        let json = serde_json::to_string(&update)?;
                        server.broadcast(json).await?;
                    },
                    _ => {}
                }
            }
        }
    });
    
    server.start().await?;
    Ok(())
}

Ready to Build?

Try these examples or create your own WebSocket application

Read Full Guide Test Your Server