Expand description
Routing and server management for WebSocket connections with middleware support.
This module provides the core routing infrastructure for WsForge, allowing you to define handlers for different message patterns, manage application state, add middleware layers, and configure server behavior. The router handles both WebSocket connections and static file serving on the same port.
§Overview
The Router is the main entry point for building a WebSocket server. It provides
a builder-style API for:
- Registering message handlers for specific routes
- Adding global and per-route middleware layers
- Managing shared application state
- Serving static files (HTML, CSS, JS)
- Configuring connection lifecycle callbacks
- Managing WebSocket connections
§Architecture
┌─────────────────┐
│ TCP Listener │
└────────┬────────┘
│
├──→ HTTP Request → Static File Handler
│
└──→ WebSocket Upgrade → Connection Manager
│
├──→ on_connect callback
│
├──→ Global Middleware Chain
│ ├──→ Middleware 1
│ ├──→ Middleware 2
│ └──→ Route-Specific Middleware
│ └──→ Handler
│
└──→ on_disconnect callback§Middleware System
WsForge supports a powerful middleware system with two types:
- Global middleware: Applied to all routes
- Per-route middleware: Applied only to specific routes
Middleware execute in order: global first, then per-route, then the handler.
§Examples
§Simple Echo Server
use wsforge::prelude::*;
async fn echo(msg: Message) -> Result<Message> {
Ok(msg)
}
let router = Router::new()
.default_handler(handler(echo));
router.listen("127.0.0.1:8080").await?;§With Global Middleware
use wsforge::prelude::*;
async fn echo(msg: Message) -> Result<Message> {
Ok(msg)
}
let router = Router::new()
.layer(LoggerMiddleware::new()) // Logs all messages
.default_handler(handler(echo));
router.listen("127.0.0.1:8080").await?;§Multiple Routes with Per-Route Middleware
use wsforge::prelude::*;
async fn public_handler(msg: Message) -> Result<String> {
Ok("Public response".to_string())
}
async fn admin_handler(msg: Message) -> Result<String> {
Ok("Admin response".to_string())
}
let router = Router::new()
// Public route - no auth needed
.route("/public", handler(public_handler))
// Admin route - with auth middleware
.route_with_layers(
"/admin",
vec![auth_middleware()],
handler(admin_handler)
);
router.listen("127.0.0.1:8080").await?;§With State and Callbacks
use wsforge::prelude::*;
use std::sync::Arc;
async fn broadcast(msg: Message, State(manager): State<Arc<ConnectionManager>>) -> Result<()> {
manager.broadcast(msg);
Ok(())
}
let router = Router::new()
.layer(LoggerMiddleware::new())
.default_handler(handler(broadcast))
.on_connect(|manager, conn_id| {
println!("✅ User {} connected (Total: {})", conn_id, manager.count());
})
.on_disconnect(|manager, conn_id| {
println!("❌ User {} disconnected", conn_id);
});
router.listen("127.0.0.1:8080").await?;