Pattern for multi-station persistent signalr connection

What is the correct JavaScript template to connect to SignalR and keep in touch while they are on the page, whether people are dormant on their computers or have spotty internet connections.

The documentation only says:

$.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 into account disconnections and other issues.

In addition, it does not capture the issue of session expiration and requires a re-entry into the system.

+6
source share
3 answers

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

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

So, if we do not focus on how to make a permanent connection that will never work, we could focus on giving the user an idea of ​​this, skillfully managing the shutdown, rebooting, etc. in the background.

Here is a diagram showing how I would configure this, even if you do not specify what causes your hub to output data to clients, but I get an image, it might be something like this diagram. The idea here is that you click the same state on some state provider, that is, on the cache, the web api repository, so that you have the whole set of available data at any given time. When ui boots or disconnects, it must send a request to this provider to restore the state, and then it must reconnect to the hub.

If data consistency is a problem, you can perform state versioning, save a local copy in ui, and then audit when reconnecting. Thus, you could see if you missed something, and in this case you will issue catch-up requests to the state provider.

Permanent Link Fabrication Pattern

To handle events, you simply use some functions on your client side: // this will cause all state changes during the connection loop:

 $.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 works when disconnected from the hub.

 $.connection.hub.disconnected(function () { console.log('Connection disconnected') }); 
+2
source

The only way I can do this is to use a backplane that stores the connection information of each connected client. However, they will never “stay in touch”. If they have lost internet or hibernation, all you can do is reconnect. In case of disconnection, you will need to store any status information on an ongoing basis, you cannot do this in the “disconnect” event, because by then it is probably too late. One option would be to constantly transmit status information to the redis cache and periodically send it to the back plane for more reasonable intervals or when even the lights are turned off.

+1
source

It turned out how to end the session by transferring all calls to the server using retry:

 function callServer(call) { function err(r?: Error) { var output = $.Deferred(); if (r && r.message && (r.message.startsWith("Caller is not authorized to invoke the") || r.message.startsWith("The user identity cannot change during "))) { $('#login-dialog') .one('hide.bs.modal', () => { hub.connection.stop(); $.connection.hub.start() .then(() => hub.server.run(call)) .then(output.resolve, output.reject); }) .modal('show'); return output; } // ReSharper disable once SuspiciousThisUsage return output.rejectWith(this, <any>arguments); } return $.connection.hub.start() .then(() => hub.server.run(call)) .then(null, err); } 

This assumes a modal dialog boottrap #login-dialog , which when closed means that it handled re-login.

0
source

Source: https://habr.com/ru/post/1011540/


All Articles