In this article, we are going to learn how to implement Automatic Reconnect in SignalR. We have already discussed how to implement a real-time chart using ASP.NET Core SignalR on the server-side and Angular in the client-side in our .NET Core with SignalR and Angular – Real-Time charts article.

The completed source code of the linked article is a good starting point for this article and we’ll make our changes on top of that.
We highly recommend reading that article first and trying out the project we created there. That will help you understand the concept of ASP.NET Core SignalR and will make it easy to follow along with this article. 

Furthermore, we have learned how to send messages to a specific client in the SignalR- Send Client-Specific messages article. However, while implementing a SignalR solution, we often come across an issue of connection getting lost intermittently. Once the SignalR disconnects, we lose the real-time behavior of our application. Then, we need to establish the connection again for the application to function properly. SignalR does not reconnect automatically after a disconnection.

Previously, we had to implement custom mechanisms for the automatic reconnection of SignalR. But that is not a straightforward task. We need to take many things into account while implementing such a solution. The good news is that, in ASP.NET Core 3.0, SignalR introduced the automatic reconnect feature which will help us to solve this problem. In this article, we are going to look at that feature and how to implement that in our SignalR app.

To download the source code for this article, you can visit our SignalR Automatic Reconnect Option repository.

We have divided this article into the following sections:

The SignalR Disconnection Problem

SignalR uses WebSockets under the hood which enables the two-way communication between the browser and the server. That means it will use WebSockets whenever available, and gracefully fall back to other techniques when a WebSocket connection cannot be established. Generally, WebSocket connections get disconnected automatically after a while.

Let’s take a look at the SignalR app that we created in the previous article

signalr disconnect after some time

We can see that once we run the app and keep it idle, the SignalR disconnects after some time. Once it disconnects, we can see an error message in the browser console.

On losing the connection, SignalR does not automatically attempt to reconnect. So we’ll lose the real-time behavior of our app. Then, the only way to re-establish the connection is by refreshing the page. This presents an unpleasant experience for the users.

SignalR Automatic Reconnect Option

As we discussed in the introduction, SignalR has added the support for automatic reconnect in ASP.NET Core 3.0. For this to work, the SignalR Javascript Client version should be 3.0.0 or above. We can configure the Javascript client for SignalR to automatically reconnect using the withAutomaticReconnect() method on HubConnectionBuilder. However, it is not the default behavior and we need to call this method explicitly.

We can customize the behavior of withAutomaticReconnect() by providing an argument. It accepts an array of millisecond values as an argument. This denotes the time the client waits before it attempts each reconnection. If we do not pass any parameters, withAutomaticReconnect() configures the client to wait for 0, 2, 10, and 30 seconds respectively before attempting each reconnection. Finally, it will stop after four failed attempts. 

This is equivalent to passing [0, 2000, 10000, 30000, null] as the argument. We can customize the number of retry attempts and delays by passing the desired values as an array in the argument. 

Implementing SignalR Automatic Reconnect

We have looked at the automatic reconnect option available in SignalR. Now, without any further ado, let’s implement the same in our project. We are going to modify the project that we created in the linked article

To have this support, first, we need to upgrade the Javascript SignalR library to the latest version. We can do that by installing the @aspnet/[email protected] npm package:

npm install @aspnet/[email protected]

Then, we are going to modify the startConnection() method of the SignalRService class to enable automatic reconnect. 
public startConnection = () => {
  this.hubConnection = new signalR.HubConnectionBuilder()
                          .withUrl('https://localhost:5001/chart')
                          .withAutomaticReconnect()
                          .configureLogging(signalR.LogLevel.Information)
                          .build();

  this.hubConnection
    .start()
    .then(() => console.log('Connection started'))
    .catch(err => console.log('Error while starting connection: ' + err))
}

Here, we call the withAutomaticReconnect() method without any parameters. So this will wait for 0, 2, 10, and 30 seconds respectively before attempting each reconnection. Finally, it will stop after four failed attempts. Of course, we can customize this by passing a set of custom values as the argument.

Furthermore, we have made a call to the configureLogging() method by passing the LogLevel argument as LogLevel.Information. This will configure console logging for the HubConnection instance. The LogLevel.Information argument will enable logging of all events of severity Information or more into the console. We’ve done this so that we can get a log of all events happening in the background.

That’s it. We have configured our SignalR app for automatic reconnection.

Testing

Now, let’s test the automatic reconnection behavior of our SignalR app.

For that, we have to run both our server and client app. We can see that the Angular app displays the chart. The server-side application keeps on updating the chart values at regular intervals:

signalr app running

Now, we are going to simulate a WebSocket disconnection scenario. For that, we just need to stop our server application for a few seconds and start it again. We can see that the real-time updates on our Angular app stop for some time when the server application is stopped. But, once our server application is back online, the WebSocket connection will be automatically established again. Cool!

Let’s observe the console to understand the events happening in the background: 

signalr automatic reconnect

Here, we can see that initially the WebSocket connection is established and our client app gets real-time data from the server application.

Then, once we stop the server application, the WebSocket gets disconnected. It immediately makes the first attempt to reconnect, but fails.

After that, it attempts another reconnect in 2 seconds, which fails as well. We can see that the next attempt is made after 10 seconds and by that time, our server application is back online and then the connection becomes successful.

In a real-world scenario, the server application would start sending data once the connection is re-established. But here, since we stopped the server application to simulate WebSocket disconnection, it causes the Timer to stop as well. Remember that we are using a Timer to send data to the client. Hence, real-time data is not pushed to the client app after reconnecting.

However, as we now understand how to enable automatic reconnection of SignalR, we can create a lot of cool stuff using this.

Conclusion

In this article we looked at the following topics:  

  • The disconnection problem of SignalR
  • Automatic Reconnect feature of SignalR
  • How to implement the automatic reconnection in our SignalR app