π‘ SignalR Real-time Updates
WebSocket-based live dashboard and notification system
π Implementation Status
SignalR real-time updates are planned but not yet implemented. Current dashboard updates require page refresh or polling. This document outlines the proposed architecture for live updates.
β Not Implemented
β Planned Q3 2026
High Priority
ποΈ Proposed SignalR Architecture
SignalR Real-time Architecture (Proposed)
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β CURRENT STATE (Polling) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β Angular Dashboard API Database β
β β β β β
β β GET /dashboard β β β
β ββββββββββββββββββΊβ β β
β β β SELECT... β β
β β βββββββββββββββββββββββββΊβ β
β β ββββββββββββββββββββββββββ β
β ββββββββββββββββββββ β β
β β β β β
β β (Wait 30s) β β β
β β β β β
β β GET /dashboard β β β
β ββββββββββββββββββΊβ β β
β β ...repeat... β β β
β β
β β Problems: β
β β’ Wasted resources (constant polling) β
β β’ Delayed updates (30s polling interval) β
β β’ Server load (N clients Γ M requests) β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β PROPOSED STATE (SignalR) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β ββββββββββββββββ ββββββββββββββββ βββββββββββββ β
β β Agent β β SignalR Hub β β Redis β β
β β (Tray) β β (Backplane) β β (Pub/Sub)β β
β ββββββββ¬ββββββββ ββββββββ¬ββββββββ βββββββ¬ββββββ β
β β β β β
β β Session Events β β β
β β (AI detected) β β β
β ββββββββββββββββββββββββββββββββΊβ β β
β β β β β
β β β Broadcast to Group β β
β β β (OrganizationId) β β
β β βββββββββββββββββββββββββββββΊβ β
β β β β β
β β ββββββββββββββββββββββββββββββ β
β β β β β
β ββββββββ΄ββββββββ ββββββββ΄ββββββββ βββββββ΄ββββββ β
β β Angular β β API Server β β Database β β
β β Dashboard ββββββββββββββββ (Hub Host) β β β β
β β β WebSocket β β β β β
β ββββββββββββββββ ββββββββββββββββ βββββββββββββ β
β β
β Hub Groups (Tenant Isolation): β
β β’ group:org-123 β Users in organization 123 β
β β’ group:admin β All admin users β
β β’ group:superadmin β SuperAdmin only β
β β
β Benefits: β
β β’ Instant updates (WebSocket push) β
β β’ Reduced server load (persistent connections) β
β β’ Scalable with Redis backplane β
β β’ Bidirectional communication (notifications, alerts) β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
π‘ Real-time Event Types
| Event | Source | Target Group | Payload | Use Case |
|---|---|---|---|---|
SessionStarted |
Agent | org:{orgId} | { sessionId, userId, startTime } | Live activity feed |
SessionEnded |
Agent | org:{orgId} | { sessionId, duration, aiUsageTime } | Real-time dashboard KPI update |
AIDetected |
Agent | org:{orgId} | { tool, duration, userId } | AI usage tracking |
DashboardUpdate |
Backend | org:{orgId} | { metrics, trends } | Aggregated dashboard refresh |
ExportCompleted |
ExportJob | user:{userId} | { jobId, downloadUrl } | Export ready notification |
Alert |
System | org:{orgId} or user:{userId} | { type, message, severity } | System notifications |
UserJoined |
Auth | org:{orgId} | { userId, email, timestamp } | Activity monitoring |
π Security Model
SignalR Authentication & Authorization
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
WebSocket Connection Establishment:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
1. Client Requests Connection Upgrade
GET /hubs/analytics?access_token=eyJhbG...
Headers:
β’ Authorization: Bearer {JWT}
β’ X-Organization-Id: org-123
β
βΌ
2. Server Validates JWT
βββββββββββββββββββββββββββββββββββββββ
β β’ Verify signature (RS256) β
β β’ Check expiration β
β β’ Extract claims: β
β - sub (UserId) β
β - org (OrganizationId) β
β - role β
βββββββββββββββββββββββββββββββββββββββ
β
βΌ
3. Authorize Hub Connection
βββββββββββββββββββββββββββββββββββββββ
β [Authorize(Roles = "Admin,Manager")]β
β β
β β’ Check role claim β
β β’ Verify org matches request β
β β’ Validate subscription status β
βββββββββββββββββββββββββββββββββββββββ
β
βΌ
4. Add to Tenant Group
βββββββββββββββββββββββββββββββββββββββ
β await Groups.AddToGroupAsync( β
β Context.ConnectionId, β
β $"org:{orgId}"); β
β β
β // User now receives all events β
β // broadcast to org:{orgId} β
βββββββββββββββββββββββββββββββββββββββ
5. Connection Established
WebSocket UPGRADE 101 Switching Protocols
Tenant Isolation in SignalR:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β’ Each user joins group: "org:{theirOrganizationId}"
β’ Hub methods verify Context.User belongs to target org
β’ SuperAdmins can join multiple groups or "superadmin" group
β’ Messages filtered server-side before broadcast
βοΈ Implementation Components
1. AnalyticsHub (Server)
public class AnalyticsHub : Hub
{
[Authorize]
public async Task JoinOrganizationGroup()
{
var orgId = Context.User.GetOrgId();
await Groups.AddToGroupAsync(
Context.ConnectionId, $"org:{orgId}");
}
public async Task BroadcastDashboardUpdate(
string orgId, DashboardMetrics metrics)
{
await Clients.Group($"org:{orgId}")
.SendAsync("DashboardUpdate", metrics);
}
}
2. Angular Service (Client)
@Injectable()
export class RealtimeService {
private hubConnection: HubConnection;
connect() {
this.hubConnection = new HubConnectionBuilder()
.withUrl('/hubs/analytics', {
accessTokenFactory: () => this.getJwtToken()
})
.build();
this.hubConnection.on('DashboardUpdate',
(metrics) => this.updateDashboard(metrics));
return this.hubConnection.start();
}
}
3. Event Publisher
public class SessionEventPublisher
{
private readonly IHubContext _hub;
public async Task PublishSessionStarted(
Session session)
{
await _hub.Clients
.Group($"org:{session.OrganizationId}")
.SendAsync("SessionStarted", new {
session.Id,
session.UserId,
session.StartTime
});
}
}
4. Redis Backplane
// Program.cs
builder.Services.AddSignalR()
.AddStackExchangeRedis("connectionString",
options => {
options.Configuration.ChannelPrefix =
"AIUsagePlatform";
});
// Enables multiple API servers to share connections
π Scaling Architecture
SignalR Scaling with Redis Backplane
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β MULTIPLE API SERVERS β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β βββββββββββββββββββ ββββββββββββββββ βββββββββββββββββββ β
β β API Server 1 β β Redis β β API Server 2 β β
β β (SignalR) βββββββΊβ Backplane βββββββββΊβ (SignalR) β β
β β β β β β β β
β β β’ Connections β β β’ Pub/Sub β β β’ Connections β β
β β β’ Hub instances β β β’ Scale-out β β β’ Hub instances β β
β ββββββββββ¬βββββββββ ββββββββββββββββ ββββββββββ¬βββββββββ β
β β β β
β β WebSocket connections β β
β βΌ βΌ β
β βββββββββββββββββββ βββββββββββββββββββ β
β β Angular β β Angular β β
β β Client A β β Client B β β
β βββββββββββββββββββ βββββββββββββββββββ β
β β
β When Server 1 broadcasts to group "org:123": β
β 1. Server 1 publishes to Redis channel "org:123" β
β 2. Redis forwards to Server 2 β
β 3. Server 2 delivers to its connected clients in org:123 β
β β
β Result: Client B receives message even though connected to Server 2 β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β οΈ Implementation Risks
Connection Limits
IIS/Web server has concurrent connection limits. May need dedicated SignalR service or Azure SignalR Service.
Memory Usage
Each WebSocket connection consumes memory. 10K concurrent connections = significant RAM usage.
Proxy/WebSocket Support
Corporate proxies may block WebSockets. Need fallback to Server-Sent Events or Long Polling.
β Implementation Checklist
Phase 1: Infrastructure
- Add SignalR NuGet package
- Configure Redis backplane
- Setup WebSocket support in IIS
- Configure CORS for WebSocket
Phase 2: Hub Implementation
- Create AnalyticsHub class
- Implement authentication
- Add tenant group management
- Create event publisher service
Phase 3: Frontend
- Add SignalR client library
- Create RealtimeService
- Subscribe to dashboard events
- Handle reconnection logic
Phase 4: Integration
- Hook session events to SignalR
- Hook export completion events
- Add notification system
- Load testing (10K+ connections)