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.