Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best practice for reconnecting SignalR 2.0 .NET client to server hub

I'm using SignalR 2.0 with the .NET client in a mobile application which needs to handle various types of disconnects. Sometimes the SignalR client reconnects automatically - and sometimes it has to be reconnected directly by calling HubConnection.Start() again.

Since SignalR magically auto-reconnects some of the time, I'm wondering if I'm missing a feature or config setting?

What's the best way to set up a client that reconnects automatically?


I've seen javascript examples that handle the Closed() event and then Connect after a n-seconds. Is there any recommended approach?

I've read the documentation and several articles about the lifetime of SignalR connections, but I'm still unclear on how to handle the client reconnect.

like image 822
Ender2050 Avatar asked Apr 29 '14 20:04

Ender2050


People also ask

How do I reconnect my SignalR?

Handle the disconnected event to display a message when an attempt to reconnect has timed out. In this scenario, the only way to re-establish a connection with the server again is to restart the SignalR connection by calling the Start method, which will create a new connection ID.

How do I check if my SignalR is reconnecting?

To test reconnect after the server goes down use iisreset. To simulate client connection dropping (good luck) pull the network cable :) Pulling the network cable won't accurately simulate a client connection dropping when you're using Azure SignalR Service.


1 Answers

I finally figured this out. Here's what I've learned since starting this question:

Background: We're building an iOS app using Xamarin / Monotouch and the .NET SignalR 2.0.3 client. We're using the default SignalR protocols - and it seems to be using SSE instead of web sockets. I'm not sure yet if it's possible to use web sockets with Xamarin / Monotouch. Everything is hosted using Azure websites.

We needed the app to reconnect to our SignalR server quickly, but we kept having problems where the connection didn't reconnect on its own - or the reconnect took exactly 30 seconds (due to an underlying protocol timeout).

There were three scenarios we ended up testing for:

Scenario A - connecting the first time the app was loaded. This worked flawlessly from day one. The connection completes in less than .25 seconds even over 3G mobile connections. (assuming the radio is already on)

Scenario B - reconnecting to the SignalR server after the app was idle/closed for 30 seconds. In this scenario, the SignalR client will eventually reconnect to the server on its own without any special work - but it seems to wait exactly 30 seconds before attempting to reconnect. (way too slow for our app)

During this 30 second waiting period, we tried calling HubConnection.Start() which had no effect. And calling HubConnection.Stop() also takes 30 seconds. I found a related bug on the SignalR site that appears to be resolved, but we're still having the same problem in v2.0.3.

Scenario C - reconnecting to the SignalR server after the app was idle/closed for 120 seconds or longer. In this scenario, the SignalR transport protocol has already timed out so the client never automatically reconnects. This explains why the client was sometimes but not always reconnecting on its own. The good news is, calling HubConnection.Start() works almost instantly like scenario A.

So it took me a while to realize that the reconnect conditions were different based on whether the app was closed for 30 seconds vs 120+ seconds. And although the SignalR tracing logs illuminate what's going on with the underlying protocol, I don't believe there's a way to handle the transport level events in code. (the Closed() event fires after 30 seconds in scenario B, instantly in scenario C; the State property says "Connected" during these reconnect waiting periods; no other relevant events or methods)

Solution: The solution is obvious. We're not waiting for SignalR to do its reconnection magic. Instead, when the app is activated or when the phone's network connection is restored, we're simply cleaning up the events and de-referencing the HubConnection (can't dispose it because it takes 30 seconds, hopefully garbage collection will take care of it) and creating a new instance. Now everything is working great. For some reason, I thought we should be reusing a persisted connection and reconnecting instead of just creating a new instance.

like image 166
Ender2050 Avatar answered Sep 19 '22 05:09

Ender2050