File tree Expand file tree Collapse file tree 2 files changed +22
-2
lines changed
Expand file tree Collapse file tree 2 files changed +22
-2
lines changed Original file line number Diff line number Diff line change 5555// Add SignalR for real-time dashboard updates
5656// Educational Note: SignalR provides WebSocket-based real-time communication,
5757// which is essential for showing live metrics on the dashboard.
58- builder . Services . AddSignalR ( )
58+ builder . Services . AddSignalR ( options =>
59+ {
60+ // Configure timeouts to prevent connections from hanging indefinitely
61+ // during simulated performance problems (thread starvation, crashes, etc.)
62+ options . ClientTimeoutInterval = TimeSpan . FromSeconds ( 60 ) ; // Disconnect if no message for 60s
63+ options . KeepAliveInterval = TimeSpan . FromSeconds ( 15 ) ; // Send keepalive every 15s
64+ options . HandshakeTimeout = TimeSpan . FromSeconds ( 15 ) ; // Handshake must complete in 15s
65+
66+ // Enable detailed errors for debugging (disable in production)
67+ options . EnableDetailedErrors = builder . Environment . IsDevelopment ( ) ;
68+ } )
5969 . AddJsonProtocol ( options =>
6070 {
6171 // Use camelCase to match controller JSON serialization
Original file line number Diff line number Diff line change @@ -93,6 +93,14 @@ async function initializeSignalR() {
9393 . configureLogging ( signalR . LogLevel . Information )
9494 . build ( ) ;
9595
96+ // Configure timeouts to detect server unresponsiveness faster
97+ // serverTimeoutInMilliseconds: How long client waits for server response before disconnecting
98+ // Must be at least 2x the server's KeepAliveInterval (15s), so we use 45s
99+ state . connection . serverTimeoutInMilliseconds = 45000 ;
100+
101+ // keepAliveIntervalInMilliseconds: How often client sends ping to server
102+ state . connection . keepAliveIntervalInMilliseconds = 15000 ;
103+
96104 // Handle connection state changes
97105 state . connection . onreconnecting ( error => {
98106 updateConnectionStatus ( 'connecting' , 'Reconnecting...' ) ;
@@ -106,7 +114,9 @@ async function initializeSignalR() {
106114
107115 state . connection . onclose ( error => {
108116 updateConnectionStatus ( 'disconnected' , 'Disconnected' ) ;
109- logEvent ( 'error' , 'Connection closed. Refresh page to reconnect.' ) ;
117+ logEvent ( 'warning' , 'Connection closed. Attempting to reconnect...' ) ;
118+ // Auto-reconnect after close (handles cases where withAutomaticReconnect gives up)
119+ setTimeout ( initializeSignalR , CONFIG . reconnectDelayMs ) ;
110120 } ) ;
111121
112122 // Register message handlers
You can’t perform that action at this time.
0 commit comments