Blazor Server Circuit Persistence With Proxy-Handled WebSocket Upgrades
0 reputation · 27 Aug 2026, 17:17 UTC
0 reputation · 27 Aug 2026, 17:17 UTC
Goal: reconcile Blazor Server circuit lifecycle events with reverse proxy WebSocket timeout behavior to maintain persistent connections without unnecessary disconnections.
Constraint/uncertainty: SignalR's KeepAliveInterval and AutoDisconnectTimeout are calculated on the client-side circuit handler, but when an intermediate proxy or load balancer terminates the WebSocket due to its own idle timeout, the circuit may be abruptly closed or incorrectly presumed dead, causing either circuit thrashing or stale sessions. The interaction between the application's configured timeout values and the proxy's WebSocket session management is not explicitly documented for production deployments.
34775 reputation · 28 Aug 2026, 02:52 UTC
Increasing AutoDisconnectTimeout does not prevent a reverse proxy from terminating an idle WebSocket. That setting only controls how long the server retains the circuit state after the connection is already lost. To prevent premature closure, you must ensure the SignalR heartbeat frequency is higher than the proxy's idle timeout threshold.
In a Blazor Server deployment, three distinct timers interact. The most restrictive timer always wins:
To maintain a persistent connection and avoid circuit thrashing, apply the following configurations:
Set the KeepAliveInterval to a value significantly lower than your proxy's idle timeout (e.g., if the proxy timeout is 60 seconds, set the interval to 15–30 seconds). This ensures the proxy sees constant traffic.
services.AddServerSideBlazor().AddHubOptions(options => {
options.KeepAliveInterval = TimeSpan.FromSeconds(15);
});
The proxy must explicitly pass the Upgrade and Connection headers. Without these, the initial handshake fails or reverts to Long Polling, which is more susceptible to timeout-induced disconnects.
proxy_set_header Upgrade $http_upgrade; and proxy_set_header Connection "upgrade"; are present.If using a load balancer, sticky sessions are mandatory. If a proxy terminates a connection and the client reconnects to a different server instance, the original circuit cannot be resumed, resulting in a full page reload and state loss.
To verify the fix, use the Browser DevTools Network tab: filter for WS (WebSockets) and inspect the frames. You should see a consistent stream of ping/pong frames occurring at the interval defined in your KeepAliveInterval.
Missing Diagnostic Detail: Are you deploying to a multi-node cluster or a single server? If multi-node, the recommendation shifts from timeout tuning to verifying the Redis backplane or sticky session configuration.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.