Practical examples to help you get started with WebSocket RS
A basic server that echoes back all messages it receives.
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(())
}
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!"
};
A multi-room chat server where users can join different rooms and broadcast messages.
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(())
}
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);
};
Stream live data updates to connected clients for monitoring dashboards.
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(())
}
<!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>
Send real-time notifications to connected clients with targeting options.
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(())
}
Secure your WebSocket connections with JWT authentication.
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(())
}
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');
};
Real-time game state synchronization for multiplayer games.
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(())
}
Try these examples or create your own WebSocket application