SignalR and Browser Connection limit

This problem would be best addressed by the future Channel Messaging specification, which has not been implemented by any browsers to-date, but I managed to solve it by limiting the number of connections as described by Alex Ford and using localStorage as a message bus between tabs.

The storage event lets you propagate data between tabs while keeping a single SignalR connection open (thereby preventing connection saturation). Calling localStorage.setItem('sharedKey', sharedData) will raise the storage event in all other tabs (not the caller):

$(window).bind('storage', function (e) {
    var sharedData = localStorage.getItem('sharedKey');
    if (sharedData !== null)
        console.log(
            'A tab called localStorage.setItem("sharedData",'+sharedData+')'
        );
});

You can test if ($.connection.hub.state === 1) to determine if a given tab should notify the other tabs via localStorage (courtesy of Alex) to prevent duplicate localStorage.setItem calls.

Facebook overcomes this browser limitation by serving persistent connections over several sub-domains, but this can complicate deployment and testing.

Caveats

Old Connections: In Alex’s solution, you need to be careful of Disconnect() not being called (e.g. exception), and you filling up your HubConnections bucket (or repository) with old hub connections. If the Session ID does not change (can happen), this may prevent new clients from establishing a SignalR connection even though none are active. Alternatively, timestamp new connections and have a sliding expiration to minimise potential impact.

Locking: localStorage may be subject to race conditions as it does not implement any locking as described here.

To support different types of events, you should encode an eventType in your JSON messages and test for it on the storage event.

Fallbacks

If a SignalR connection cannot be established, I fall back onto polling the server every 45 seconds to retrieve a notification count.

If you don’t want to use localStorage, you can use cookies, but it’s not as clean.

Leave a Comment