reinhardt_websockets/lib.rs
1//! WebSocket support for Reinhardt framework
2//!
3//! This crate provides comprehensive WebSocket support for the Reinhardt framework,
4//! including connection management, room-based messaging, authentication, rate limiting,
5//! middleware integration, and distributed channel layers.
6//!
7//! ## Features
8//!
9//! - **Connection Management**: Robust WebSocket connection handling with lifecycle hooks
10//! - **Room-Based Messaging**: Group connections into rooms for targeted broadcasting
11//! - **Authentication & Authorization**: Token-based auth and permission-based authorization
12//! - **Rate Limiting**: Connection and message rate limiting to prevent abuse
13//! - **Middleware Integration**: Pre-processing and post-processing of connections and messages
14//! - **WebSocket Routing**: URL-based WebSocket endpoint registration
15//! - **Channel Layers**: Distributed messaging for multi-instance deployments
16//! - **Consumer Classes**: Django Channels-inspired message handling patterns
17//!
18//! ## Basic Usage
19//!
20//! ```
21//! use reinhardt_websockets::{WebSocketConnection, Message};
22//! use tokio::sync::mpsc;
23//! use std::sync::Arc;
24//!
25//! # tokio_test::block_on(async {
26//! let (tx, mut rx) = mpsc::unbounded_channel();
27//! let conn = Arc::new(WebSocketConnection::new("user_1".to_string(), tx));
28//!
29//! conn.send_text("Hello, WebSocket!".to_string()).await.unwrap();
30//!
31//! let msg = rx.recv().await.unwrap();
32//! match msg {
33//! Message::Text { data } => println!("Received: {}", data),
34//! _ => {}
35//! }
36//! # });
37//! ```
38//!
39//! ## Advanced Features
40//!
41//! ### Message Compression
42//!
43//! The `compression` feature enables gzip, deflate, and brotli compression for WebSocket messages:
44//!
45//! ```toml
46//! [dependencies]
47//! reinhardt-websockets = { version = "0.1", features = ["compression"] }
48//! ```
49//!
50//! ### Automatic Reconnection
51//!
52//! The `reconnection` module provides automatic reconnection with exponential backoff:
53//!
54//! ```
55//! use reinhardt_websockets::reconnection::{ReconnectionConfig, ReconnectionStrategy};
56//! use std::time::Duration;
57//!
58//! let config = ReconnectionConfig::default()
59//! .with_max_attempts(5)
60//! .with_initial_delay(Duration::from_secs(1));
61//!
62//! let mut strategy = ReconnectionStrategy::new(config);
63//! ```
64//!
65//! ### Redis Channel Layer
66//!
67//! The `redis-channel` feature enables distributed messaging via Redis:
68//!
69//! ```toml
70//! [dependencies]
71//! reinhardt-websockets = { version = "0.1", features = ["redis-channel"] }
72//! ```
73//!
74//! ### Metrics and Monitoring
75//!
76//! The `metrics` module provides comprehensive WebSocket metrics:
77//!
78//! ```
79//! use reinhardt_websockets::metrics::{WebSocketMetrics, MetricsCollector};
80//!
81//! let metrics = WebSocketMetrics::new();
82//! metrics.record_connection();
83//! metrics.record_message_sent();
84//!
85//! let snapshot = metrics.snapshot();
86//! println!("{}", snapshot.summary());
87//! ```
88//!
89//! ### Integration with reinhardt-pages
90//!
91//! The `pages-integration` feature enables seamless integration with reinhardt-pages,
92//! allowing WebSocket connections to use the same Cookie/session-based authentication
93//! as the HTTP layer:
94//!
95//! ```toml
96//! [dependencies]
97//! reinhardt-websockets = { version = "0.1", features = ["pages-integration"] }
98//! ```
99//!
100//! **Server-side setup:**
101//!
102//! ```ignore
103//! use reinhardt_websockets::{PagesAuthenticator, WebSocketRouter, WebSocketRoute};
104//! use std::sync::Arc;
105//!
106//! // Create authenticator that integrates with reinhardt-pages sessions
107//! let authenticator = Arc::new(PagesAuthenticator::new());
108//!
109//! // Register WebSocket routes
110//! let mut router = WebSocketRouter::new();
111//! router.register_route(WebSocketRoute::new(
112//! "/ws/chat".to_string(),
113//! Some("websocket:chat".to_string()),
114//! )).await.unwrap();
115//! ```
116//!
117//! **Client-side usage (WASM):**
118//!
119//! On the client side, use the `use_websocket` hook from reinhardt-pages:
120//!
121//! ```ignore
122//! use reinhardt_pages::reactive::hooks::{use_websocket, UseWebSocketOptions};
123//!
124//! let ws = use_websocket("ws://localhost:8000/ws/chat", UseWebSocketOptions::default());
125//!
126//! // Send message
127//! ws.send_text("Hello, server!".to_string()).ok();
128//!
129//! // Monitor connection state
130//! use_effect({
131//! let ws = ws.clone();
132//! move || {
133//! match ws.connection_state().get() {
134//! ConnectionState::Open => log!("Connected"),
135//! ConnectionState::Closed => log!("Disconnected"),
136//! _ => {}
137//! }
138//! None::<fn()>
139//! }
140//! });
141//! ```
142//!
143//! The authentication cookies from the user's HTTP session are automatically included
144//! in the WebSocket handshake, allowing the server to authenticate the connection.
145
146pub mod auth;
147pub mod channels;
148#[cfg(feature = "compression")]
149pub mod compression;
150pub mod connection;
151pub mod consumers;
152pub mod handler;
153#[cfg(feature = "pages-integration")]
154pub mod integration;
155pub mod metrics;
156pub mod middleware;
157pub mod origin;
158pub mod protocol;
159pub mod reconnection;
160#[cfg(feature = "redis-channel")]
161pub mod redis_channel;
162pub mod room;
163pub mod routing;
164pub mod throttling;
165
166pub use auth::{
167 AuthError, AuthResult, AuthUser, AuthenticatedConnection, AuthorizationPolicy,
168 PermissionBasedPolicy, SimpleAuthUser, TokenAuthenticator, WebSocketAuthenticator,
169};
170pub use channels::{
171 ChannelError, ChannelLayer, ChannelLayerWrapper, ChannelMessage, ChannelResult,
172 InMemoryChannelLayer,
173};
174#[cfg(feature = "compression")]
175pub use compression::{
176 CompressionCodec, CompressionConfig, compress_message, decompress_message,
177 decompress_message_with_config,
178};
179pub use connection::{
180 ConnectionConfig, ConnectionTimeoutMonitor, HeartbeatConfig, HeartbeatMonitor, Message,
181 PingPongConfig, WebSocketConnection, WebSocketError, WebSocketResult,
182};
183pub use consumers::{
184 BroadcastConsumer, ConsumerChain, ConsumerContext, EchoConsumer, JsonConsumer,
185 WebSocketConsumer,
186};
187pub use handler::WebSocketHandler;
188#[cfg(feature = "pages-integration")]
189pub use integration::pages::{PagesAuthUser, PagesAuthenticator};
190#[cfg(feature = "metrics")]
191pub use metrics::MetricsExporter;
192pub use metrics::{MetricsCollector, MetricsSnapshot, PeriodicReporter, WebSocketMetrics};
193pub use middleware::{
194 ConnectionContext, ConnectionMiddleware, IpFilterMiddleware, LoggingMiddleware,
195 MessageMiddleware, MessageSizeLimitMiddleware, MiddlewareChain, MiddlewareError,
196 MiddlewareResult,
197};
198pub use origin::{
199 OriginPolicy, OriginValidationConfig, OriginValidationMiddleware, validate_origin,
200};
201pub use protocol::{
202 DEFAULT_MAX_FRAME_SIZE, DEFAULT_MAX_MESSAGE_SIZE, default_websocket_config,
203 websocket_config_with_limits,
204};
205pub use reconnection::{
206 AutoReconnectHandler, ReconnectionConfig, ReconnectionState, ReconnectionStrategy,
207};
208#[cfg(feature = "redis-channel")]
209pub use redis_channel::{RedisChannelLayer, RedisConfig};
210pub use room::{BroadcastResult, Room, RoomError, RoomManager, RoomResult};
211pub use routing::{
212 RouteError, RouteResult, WebSocketRoute, WebSocketRouter, clear_websocket_router,
213 get_websocket_router, register_websocket_router, reverse_websocket_url,
214};
215pub use throttling::{
216 CombinedThrottler, ConnectionRateLimiter, ConnectionThrottler, RateLimitConfig,
217 RateLimitMiddleware, RateLimiter, ThrottleError, ThrottleResult, WebSocketRateLimitConfig,
218};
219
220#[cfg(test)]
221mod tests;