问题
We are using SignalR in a large scale web application. We have deployed multiple web servers handling signalR connections. We have our own Redis backplane implemented, I have the following question: SignalR makes three calls to the server: 1) negotiate, 2) connect and 3) start. If we have a web farm behind a Load Balancer and these three calls end up going to three different servers, would the state of connections be corrupted on all three servers? What would happen in this scenario? I am not talking about message delivery.
More specifically:
Would a second webserver be able to understand the connectionId produced by the negotiate call?
What happens when the physical connection(websockets) is established on a different server and then the start call goes to another server?
I know for a fact that SignalR does not communicate the connection info between the servers. I am wondering about the state of connections in memory on these three servers. I read the another question related to this, but it talks only about message delivery. For us, message delivery is not a problem. I want to understand the final state of the connections if these three calls end up going to different servers.
The question that I already went through to get an answer: SignalR connection affinity in web-farm scenario
Since our load balancer maintains stickiness, I am unable to confirm what will happen when the stickiness goes away. I want to be prepared for that eventuality.
回答1:
Old question, but I'm taking the time to answer because I have a similar setup, albeit with different technologies. It might not completely solve your problems, but I think a lot of similarity can be drawn.
Our scenario real-time communication (i.e. chat messages). The server will notify the client at anytime when another user logs in, disconnects, etc.
Tech stack below:
Client: AngularJS App
CDN: serving static resources (HTML, CSS, images)
Load balancer: setup in Azure
Multiple WebApps: running ASP.NET Core
Multiple SQL Server databases: mirrored
The key point here is the application remains stateless throughout. At any point, a client may disconnect/reconnect and retrieve the same set of information it had before disconnecting.
Users are authenticated using a token mechanism (OAuth in our case). All user info (user id, etc.) are encrypted int he token.
Connection is established, and routed to any one of the web apps running.
Webapp stores connection info in a database table.
Webapp retrieves all "friends" of users who has a connection in the database.
Webapp sends list back to client.
Whenever a user disconnects, webapp receives disconnect event and removes record form database.
Whevenver a user reconnects, webapp adds the connection back, and sends the user the current list of online connections/clients.
It is up to the client to maintain which state it is in and how to react to updates in client lists.
This approach is similar to the one mentioned in the answer you posted in your question.
I believe the essential concept here is the backplane. It persists the state, instead of just communicating it around the servers.
A related blog post here may help: https://docs.microsoft.com/en-us/aspnet/signalr/overview/guide-to-the-api/mapping-users-to-connections
(Take a look at the "More than one server" scenario)
来源:https://stackoverflow.com/questions/33271355/signalr-connection-management-in-a-web-farm