ADR-006: SignalR for Real-time Communication
Status
Accepted - July 2024
Context
BookWorm requires real-time communication capabilities to enhance user experience and provide immediate feedback for various business scenarios. The system needs:
- Real-time Chat: Interactive chat support with AI-powered responses
- Order Updates: Live order status updates and notifications
- System Notifications: Instant system-wide alerts and announcements
- User Presence: Online/offline status and activity indicators
- Collaborative Features: Potential future collaborative book reading features
- Admin Dashboard: Real-time monitoring and system status updates
- Performance Requirements: Sub-second message delivery with high throughput
- Scalability: Support for thousands of concurrent connections
- Cross-platform Support: Web browsers, mobile apps, and desktop clients
- Security Integration: Authentication and authorization for real-time connections
Traditional HTTP polling would be inefficient for real-time scenarios, while WebSocket libraries alone would require significant custom implementation for connection management and scaling.
Decision
Adopt SignalR as the real-time communication framework for streaming AI chat responses in the BookWorm Chat service, providing bidirectional communication for interactive AI-powered conversations.
Implementation Strategy
Chat Streaming Hub
BookWorm implements a focused SignalR solution specifically for AI chat streaming:
- ChatStreamHub: Single hub dedicated to streaming AI responses
- Message Fragments: Real-time streaming of message fragments as AI generates responses
- Redis Backplane: Custom Redis backplane for cross-instance message delivery
- Stateful Reconnects: Support for connection recovery and message replay
Service Integration
- Chat Service: Primary consumer using SignalR for AI response streaming
- Redis Integration: Custom backplane implementation for scalability
- Authentication: Required authorization for all hub connections
Rationale
Why SignalR?
Technical Advantages
- Streaming Support: Built-in support for
IAsyncEnumerable
streaming - Transport Negotiation: Automatic fallback from WebSockets to alternative transports
- Connection Management: Built-in connection lifetime management and reconnection
- Custom Backplane: Integration with custom Redis backplane implementation
- Security Integration: Seamless integration with ASP.NET Core authentication
AI Chat Streaming Benefits
- Real-time AI Responses: Stream AI-generated text as it's being produced
- Message Fragments: Break long AI responses into manageable fragments
- Connection Recovery: Stateful reconnects ensure no message loss
- Rate Limiting: Built-in per-user rate limiting for hub methods
- Cancellation Support: Proper cancellation of AI generation streams
Implementation Overview
BookWorm's SignalR implementation focuses specifically on AI chat streaming rather than general real-time communication.
Implementation Architecture
Client-Side Implementation
JavaScript Client Integration
const chatConnection = new signalR.HubConnectionBuilder()
.withUrl("/chathub", {
accessTokenFactory: () => getAccessToken()
})
.withAutomaticReconnect([0, 2000, 10000, 30000])
.configureLogging(signalR.LogLevel.Information)
.build();
chatConnection.on("ReceiveMessage", (message) => {
displayChatMessage(message);
});
chatConnection.onreconnected(() => {
console.log("Reconnected to chat hub");
rejoinChatRooms();
});
Mobile Client Integration
// Xamarin/MAUI client
var orderConnection = new HubConnectionBuilder()
.WithUrl("https://api.bookworm.com/orderhub", options =>
{
options.AccessTokenProvider = () => Task.FromResult(GetAccessToken());
})
.WithAutomaticReconnect()
.Build();
orderConnection.On<string, OrderStatus>("OrderStatusChanged",
(orderId, status) =>
{
Device.BeginInvokeOnMainThread(() =>
{
UpdateOrderStatus(orderId, status);
});
});
Scaling and Performance
Redis Backplane Configuration
Scale-out Setup
services.AddSignalR()
.AddStackExchangeRedis(connectionString, options =>
{
options.Configuration.ChannelPrefix = "bookworm";
});
Connection Distribution
Performance Optimization
Connection Management
- Connection Pooling: Efficient connection reuse
- Heartbeat: Automatic connection health monitoring
- Reconnection: Exponential backoff for reconnection attempts
- Message Buffering: Client-side message queuing during disconnection
Message Optimization
- MessagePack: Binary serialization for high-throughput scenarios
- Compression: Automatic message compression for large payloads
- Batching: Message batching for improved throughput
- Selective Broadcasting: Targeted message delivery to reduce noise
Integration with Business Services
Event-Driven Integration
Order Status Updates
Service-to-Hub Communication
public class NotificationService
{
private readonly IHubContext<NotificationHub, INotificationClient> _hubContext;
public async Task SendUserNotification(string userId, Notification notification)
{
await _hubContext.Clients.User(userId)
.ReceiveNotification(notification);
}
public async Task SendSystemAlert(SystemAlert alert)
{
await _hubContext.Clients.Group("administrators")
.ReceiveSystemAlert(alert);
}
}
Monitoring and Observability
Connection Monitoring
- Connection Count: Real-time connection count monitoring
- Connection Duration: Average connection lifetime tracking
- Message Throughput: Messages per second metrics
- Error Rates: Connection and message error tracking
Performance Metrics
- Latency: End-to-end message delivery latency
- Memory Usage: Server memory consumption for connections
- CPU Usage: SignalR processing CPU overhead
- Network Bandwidth: Message payload and frequency analysis
Key Features
AI Response Streaming
- Fragment-based Streaming: AI responses streamed as
ClientMessageFragment
objects - Stateful Reconnects: Automatic recovery from connection loss with message replay
- Cancellation Support: Proper cancellation of long-running AI generation
- Rate Limiting: Per-user rate limiting to prevent abuse
Custom Redis Integration
- Custom Backplane: Integration with BookWorm's custom Redis backplane
- Message Buffering: Redis-based message buffering for connection recovery
- Cross-instance Communication: Seamless message delivery across service instances
Consequences
Positive Outcomes
- Real-time AI Chat: Seamless streaming of AI responses for enhanced user experience
- Connection Reliability: Stateful reconnects ensure no message loss during interruptions
- Scalability: Custom Redis backplane enables horizontal scaling of chat functionality
- Security: Built-in authorization and rate limiting for secure communication
- Performance: Efficient streaming of message fragments optimized for AI responses
Challenges and Considerations
- Connection Management: Complex connection lifecycle management for streaming scenarios
- Custom Backplane: Requires maintenance of custom Redis backplane implementation
- Resource Usage: Memory and CPU overhead for maintaining persistent connections
- AI Integration: Coordination between AI generation and real-time streaming
Risk Mitigation
- Connection Recovery: Stateful reconnects with message replay capability
- Rate Limiting: Built-in protection against connection and message abuse
- Error Handling: Comprehensive error handling for AI generation failures
- Monitoring: Integration with logging and monitoring systems for observability
Implementation Status
Current Implementation
- ✅ ChatStreamHub for AI response streaming
- ✅ Stateful reconnects with message replay
- ✅ Custom Redis backplane integration
- ✅ Per-user rate limiting and authorization
- ✅ Fragment-based AI response streaming
- ✅ Cancellation support for AI generation
Future Enhancements
- Additional hub types for other real-time scenarios
- Enhanced monitoring and performance metrics
- Advanced connection grouping strategies