WebSocket Interceptors
WebSocket interceptors allow you to process and modify WebSocket data as it flows through your server using a middleware pattern. This guide shows how to implement custom interceptors for WebSocket communication.Creating Custom Interceptors
To create a custom WebSocket interceptor, implement theInterceptor interface:
Flow Control Patterns
Continue Chain (Standard)
Short-Circuit Chain
Conditional Processing
Adding Interceptors to Your Server
Once you’ve created your custom interceptor, add it to your WebSocket server:Example: Logging Interceptor
Here’s a practical example of a logging interceptor using the new middleware pattern:Advanced Examples
Authentication Interceptor with Short-Circuiting
Rate Limiting Interceptor
Data Structures
WebSocketInbound
Incoming message structure:message_type: Type of the message (e.g., “text”, “binary”, “close”, “ping”, “pong”) - Requireddata: The actual message content (bytes or str) - Requiredclose_code: Close code for close messages (optional)close_reason: Human-readable close reason (optional)is_final: Whether this is the final frame in a fragmented message (optional)
WebSocketOutbound
Outgoing message structure:target: WebSocket URL (ws:// or wss://) - Required (inherited from Outbound)message_type: Type of the message to send (e.g., “text”, “binary”, “close”, “ping”, “pong”) - Requireddata: The message content to send (bytes or str) - Requiredheaders: HTTP headers for WebSocket handshake (optional)subprotocols: List of WebSocket subprotocols (optional)close_code: Close code for close messages (optional)close_reason: Human-readable close reason (optional)
Best Practices
- Always copy data: Use
.copy()when modifying inbound/outbound data to avoid side effects - Call next_interceptor: Always call
await next_interceptor(data)unless you want to short-circuit - Handle errors gracefully: Wrap your interceptor logic in try-catch blocks
- Keep processing lightweight: Interceptors run for every message, so avoid heavy operations
- Use conditional processing: Check
message_type,target, or data content to handle different scenarios - Short-circuit when needed: Return directly without calling
next_interceptor()to stop the chain - Before/after logic: Add logic before
next_interceptor()for pre-processing, after for post-processing - Chain order matters: Interceptors execute in registration order for inbound, reverse order for outbound

