Expand description
Β§WsForge Core - High-Performance WebSocket Framework
wsforge-core is the foundational library for the WsForge WebSocket framework.
It provides type-safe, ergonomic abstractions for building real-time WebSocket applications
with exceptional performance and developer experience.
Β§Overview
WsForge Core combines the power of tokio-tungstenite with a flexible, type-safe API inspired
by modern web frameworks like Axum. Itβs designed for building production-ready WebSocket
servers that are both fast and maintainable.
Β§Key Features
- π High Performance: Built on tokio-tungstenite with zero-copy optimizations
- π§ Type-Safe Extractors: Automatic extraction of JSON, State, Connection info
- π― Flexible Handlers: Return various types - String, Message, Result, JsonResponse
- π‘ Broadcasting: Built-in broadcast, broadcast_except, and targeted messaging
- β‘ Concurrent: Lock-free connection management with DashMap
- π Lifecycle Hooks: on_connect and on_disconnect callbacks
- π Hybrid Server: Serve static files and WebSocket on same port
- π‘οΈ Type Safety: Compile-time guarantees for correctness
Β§Architecture
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Application β
β ββββββββββββββ ββββββββββββ βββββββββββββββββββββββββ β
β β Handlers β β Router β β State & Extractors β β
β ββββββββββββββ ββββββββββββ βββββββββββββββββββββββββ β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β WsForge Core β
β ββββββββββββββββ ββββββββββββββββββ βββββββββββββββββββ β
β β Connection β β Message β β Static Files β β
β β Manager β β Router β β Handler β β
β ββββββββββββββββ ββββββββββββββββββ βββββββββββββββββββ β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β tokio-tungstenite β
β (WebSocket Protocol) β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββΒ§Module Structure
connection: WebSocket connection management and lifecyclemessage: Message types and parsing utilities- [
handler]: Handler trait and response types extractor: Type-safe data extraction from messagesrouter: Routing and server managementstate: Shared application state containererror: Error types and result handlingstatic_files: Static file serving for hybrid servers
Β§Quick Start Examples
Β§Echo Server
The simplest possible WebSocket server:
use wsforge_core::prelude::*;
async fn echo(msg: Message) -> Result<Message> {
Ok(msg)
}
#[tokio::main]
async fn main() -> Result<()> {
let router = Router::new()
.default_handler(handler(echo));
router.listen("127.0.0.1:8080").await?;
Ok(())
}Β§Chat Server with Broadcasting
A real-time chat application:
use wsforge_core::prelude::*;
use std::sync::Arc;
use serde::{Deserialize, Serialize};
#[derive(Deserialize, Serialize)]
struct ChatMessage {
username: String,
text: String,
}
async fn chat_handler(
Json(msg): Json<ChatMessage>,
conn: Connection,
State(manager): State<Arc<ConnectionManager>>,
) -> Result<()> {
println!("{}: {}", msg.username, msg.text);
// Broadcast to everyone except sender
let response = serde_json::to_string(&msg)?;
manager.broadcast_except(conn.id(), Message::text(response));
Ok(())
}
#[tokio::main]
async fn main() -> Result<()> {
let router = Router::new()
.default_handler(handler(chat_handler))
.on_connect(|manager, conn_id| {
println!("β
{} connected (Total: {})", conn_id, manager.count());
})
.on_disconnect(|manager, conn_id| {
println!("β {} disconnected", conn_id);
});
router.listen("127.0.0.1:8080").await?;
Ok(())
}Β§Web Application with Static Files
Hybrid HTTP/WebSocket server:
use wsforge_core::prelude::*;
use std::sync::Arc;
async fn ws_handler(
msg: Message,
State(manager): State<Arc<ConnectionManager>>,
) -> Result<()> {
manager.broadcast(msg);
Ok(())
}
#[tokio::main]
async fn main() -> Result<()> {
let router = Router::new()
.serve_static("public") // Serve HTML/CSS/JS
.default_handler(handler(ws_handler));
// Handles both:
// http://localhost:8080/ -> public/index.html
// ws://localhost:8080 -> WebSocket handler
router.listen("0.0.0.0:8080").await?;
Ok(())
}Β§Handler Patterns
Β§Simple Handler
use wsforge_core::prelude::*;
async fn simple_handler() -> Result<String> {
Ok("Hello, WebSocket!".to_string())
}Β§With JSON Extraction
use wsforge_core::prelude::*;
use serde::Deserialize;
#[derive(Deserialize)]
struct Request {
action: String,
data: String,
}
async fn json_handler(Json(req): Json<Request>) -> Result<String> {
Ok(format!("Action: {}, Data: {}", req.action, req.data))
}Β§With State and Connection
use wsforge_core::prelude::*;
use std::sync::Arc;
async fn stateful_handler(
msg: Message,
conn: Connection,
State(manager): State<Arc<ConnectionManager>>,
) -> Result<String> {
Ok(format!(
"Connection {} | {} total connections",
conn.id(),
manager.count()
))
}Β§Extractors
WsForge provides powerful type-safe extractors:
| Extractor | Description | Example |
|---|---|---|
Message | Raw message | msg: Message |
Json<T> | JSON deserialization | Json(data): Json<MyStruct> |
Connection | Active connection | conn: Connection |
State<T> | Shared state | State(db): State<Arc<Database>> |
ConnectInfo | Connection metadata | ConnectInfo(info) |
Data | Raw bytes | Data(bytes): Data |
Β§Response Types
Handlers can return various types:
use wsforge_core::prelude::*;
// No response
async fn handler1() -> Result<()> {
Ok(())
}
// Text response
async fn handler2() -> Result<String> {
Ok("response".to_string())
}
// Raw message
async fn handler3() -> Result<Message> {
Ok(Message::text("response"))
}
// Binary response
async fn handler4() -> Result<Vec<u8>> {
Ok(vec!)[1][2][3][4]
}
// JSON response
async fn handler5() -> Result<JsonResponse<serde_json::Value>> {
Ok(JsonResponse(serde_json::json!({"status": "ok"})))
}Β§Broadcasting Patterns
Β§Broadcast to All
use wsforge_core::prelude::*;
use std::sync::Arc;
async fn broadcast_all(
msg: Message,
State(manager): State<Arc<ConnectionManager>>,
) -> Result<()> {
manager.broadcast(msg);
Ok(())
}Β§Broadcast Except Sender
use wsforge_core::prelude::*;
use std::sync::Arc;
async fn broadcast_others(
msg: Message,
conn: Connection,
State(manager): State<Arc<ConnectionManager>>,
) -> Result<()> {
manager.broadcast_except(conn.id(), msg);
Ok(())
}Β§Targeted Broadcasting
use wsforge_core::prelude::*;
use std::sync::Arc;
async fn broadcast_to_room(
msg: Message,
State(manager): State<Arc<ConnectionManager>>,
) -> Result<()> {
let room_members = vec!["conn_1".to_string(), "conn_2".to_string()];
manager.broadcast_to(&room_members, msg);
Ok(())
}Β§Error Handling
WsForge provides comprehensive error handling:
use wsforge_core::prelude::*;
async fn safe_handler(msg: Message) -> Result<String> {
// Parse JSON
let data: serde_json::Value = msg.json()?;
// Validate
if data.is_null() {
return Err(Error::custom("Data cannot be null"));
}
// Process and return
Ok("processed".to_string())
}Β§Performance Characteristics
- Connection Management: O(1) lock-free operations via DashMap
- Message Routing: O(1) handler lookup
- Broadcasting: O(n) where n is the number of connections
- Memory: Zero-copy message handling where possible
- Concurrency: Full async/await with tokio
Β§Testing
WsForge handlers are easy to test:
use wsforge_core::prelude::*;
async fn my_handler(msg: Message) -> Result<String> {
Ok(format!("Echo: {}", msg.as_text().unwrap_or("")))
}
#[tokio::test]
async fn test_handler() {
let msg = Message::text("hello");
let result = my_handler(msg).await.unwrap();
assert_eq!(result, "Echo: hello");
}Β§Production Considerations
Β§Rate Limiting
use wsforge_core::prelude::*;
use std::sync::Arc;
use tokio::sync::RwLock;
use std::collections::HashMap;
struct RateLimiter {
limits: RwLock<HashMap<String, u32>>,
}
async fn rate_limited_handler(
msg: Message,
conn: Connection,
State(limiter): State<Arc<RateLimiter>>,
) -> Result<String> {
// Check rate limit
// Process if allowed
Ok("processed".to_string())
}Β§Graceful Shutdown
use wsforge_core::prelude::*;
use tokio::signal;
#[tokio::main]
async fn main() -> Result<()> {
let router = Router::new();
tokio::select! {
_ = router.listen("127.0.0.1:8080") => {},
_ = signal::ctrl_c() => {
println!("Shutting down gracefully...");
}
}
Ok(())
}Β§Further Reading
Re-exportsΒ§
pub use connection::Connection;pub use connection::ConnectionId;pub use error::Error;pub use error::Result;pub use extractor::ConnectInfo;pub use extractor::Data;pub use extractor::Extension;pub use extractor::Extensions;pub use extractor::Json;pub use extractor::Path;pub use extractor::Query;pub use extractor::State;pub use handler::Handler;pub use handler::HandlerService;pub use handler::IntoResponse;pub use handler::JsonResponse;pub use handler::handler;pub use message::Message;pub use message::MessageType;pub use middleware::LoggerMiddleware;pub use middleware::Middleware;pub use middleware::MiddlewareChain;pub use middleware::Next;pub use router::Route;pub use router::Router;pub use state::AppState;pub use static_files::StaticFileHandler;
ModulesΒ§
- connection
- WebSocket connection management and message handling.
- error
- Error types and result handling for WsForge.
- extractor
- Type-safe data extraction from WebSocket messages and context.
- handler
- Handler traits and implementations for WebSocket message processing.
- message
- WebSocket message types and utilities.
- middleware
- Middleware system for request/response processing.
- prelude
- Commonly used types and traits for WsForge applications.
- router
- Routing and server management for WebSocket connections with middleware support.
- state
- Shared application state management.
- static_
files - Static file serving for hybrid HTTP/WebSocket servers.