Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pattern for multiday persistent signalr connection

What is the correct JavaScript pattern to connect to SignalR and maintain the link perpetually while they are on the page, no matter if people hibernate their computers or have spotty internet connections.

The documentation just says use:

$.connection.hub.start()
    .done(function(){ console.log('Now connected, connection ID=' + $.connection.hub.id); })
    .fail(function(){ console.log('Could not Connect!'); });
});

But this does not seem to take disconnects and other issues into account.

Also, it doesn't catch the problem of the session expire and requires re-login.

like image 642
Cine Avatar asked Oct 21 '16 08:10

Cine


2 Answers

Given that SignalR is a connection based client/server solution, you cannot have expectations of long sustained open connections. So as Kelso Sharp wrote in his answer, the only good thing you can do is manage the events of the connection life cycle.

Check out the documentation for all the life cycle events of a signalR connection: https://www.asp.net/signalr/overview/guide-to-the-api/hubs-api-guide-javascript-client#connectionlifetime

So if we do not focus our attention on how to make a persistent connection that never fails, we could instead focus on giving the user an impression of that, by cunningly managing the disconnects, reloads and such in the background.

Here is a diagram showing how I would setup this, even though you do not specify what causes your hub to push data out to clients, but I imaging it could be something like this diagram. The idea here is that you push the same state to some kind of state provider - i.e. cache, web api storage, so that you have the entire set of data available at any given time. When ui loads or disconnects, it should issue a request to this provider to regain state, and then it should reconnect to the hub.

If data consistency is a issue, you could do versioning of the state, keep a local copy in the ui, and then do an audit upon reconnecting. That way you could see if you missed out on something, in which case you would issue catch up requests to the state provider.

Pattern for faking persistent connection

To handle the events you just have hook in some functions on your client side: //this will trigger for all state changes during the connection cycle:

$.connection.hub.stateChanged(function (change) {
    if (change.newState === $.signalR.connectionState.reconnecting) {
        console.log("liveFeed is reconnecting!");
    }
    else if (change.newState === $.signalR.connectionState.connected) {
        console.log("liveFeed is connected!");
    }
});

//this triggers when the disconnecting to the hub.

$.connection.hub.disconnected(function () {
   console.log('Connection disconnected')
});
like image 128
Espen Avatar answered Nov 04 '22 16:11

Espen


The only way that I that I think this can be done is to use a backplane that stores connection info of each connected client. That said, they will never "Stay Connected" If they lost internet or hibernate, all that you can do is "reconnect" You will have to store any state information on a continual basis in the event of a disconnection, you cannot do this in the "disconnect" event because by then it is likely too late. One option would be to continually stream state info to a redis cache and periodically send it to that the back plane in more reasonable intervals, or when the disconnected even fires.

like image 25
Kelso Sharp Avatar answered Nov 04 '22 16:11

Kelso Sharp