2
votes

I'm working on an asp.net core 2.2 MVC web application. We are using signal r core version 1.1.0 (added via the nuget package Microsoft.AspNetCore.SignalR). The client side application is an angularjs application referencing version 1.1.4 of the aspnet-signalr javascript library.

Our application is deployed on Azure and the hosting app service is scaled horizontally : there currently two instances of our web application up and running. I'm testing the behavior of my application by using Google chrome version 75.0.3770.100 on a windows 10 machine.

The app service is configured so that the web sockets are enabled and the ARR affinity is disabled. I'm experiencing a strange behavior, basically if I test my application and I perform several browser hard refresh (ctrl + F5) it happens randomly that the client side application is unable to connect to the notification hub. The following errors are reported in the google chrome console:

WebSocket connection to 'wss://myapp.azurewebsites.net/notificationsHub?id=3Fmlw2yC5qm3vi0qny50Qg' failed: Error during WebSocket handshake: Unexpected response code: 404

Error: Failed to start the transport 'WebSockets': null

GET https://myapp.azurewebsites.net/notificationsHub?id=nEYPEDw5f0AkLz5otCAOyA 404

Error: Failed to start the transport 'ServerSentEvents': Error: Error occurred

GET https://myapp.azurewebsites.net/notificationsHub?id=2G9VVr5mcx7QT2wbSfwDLA&_=1561652513485 404

Error: Failed to start the transport 'LongPolling': Error

Error: Failed to start the connection: Error: Unable to initialize any of the available transports.

If I change the app service configuration so that both the web sockets and the ARR affinity are enabled everything works like a charm. My suspicious is that when the app service is horizontally scaled then the ARR affinity is required regardless of the transport protocol (in my case, both the server side application and the client browser are able to support the web socket protocol).

Based on my understanding, the official microsoft documentation states that when using web sockets as a communication protocol the client ARR affinity is not required, even if the hosting app service is horizontally scaled to multiple instances. At this point I'm not sure about my understanding of the signalr core documentation.

Am i missing something ? Did I misunderstood the official documentation ?

EDIT 3 JULY 2019

For the ones interested to this subject (scaling out a web application using signal-r core), you can refer to this github issue for all the details.

The short answer is that the new signal-r core is actually stateful and requires sticky sessions when the application is scaled out to multiple servers.

If you are on Azure only, you can avoid the usage of sticky sessions and have several other benefits by using the Azure signalr service.

If you don't want to use this azure service the only option to avoid sticky sessions is configuring signal r core so that the client-server protocol negotiation is avoided and the communication is done by using web sockets only (refer to the linked github issue for all the details). Notice that doing so you will lose the ability of downgrading to other protocols when web sockets aren't supported, which is one of the core features of signal-r core.

1

1 Answers

2
votes

If you want to affinity disable, then I think the component you're missing is the hosted SignalR service. It's the proxy service that will maintain session info for you as your app service scales out. Follow these steps to add SignalR service as a service dependency to your project.