I am having a strange issue with SignalR through different load balancers (I have tried elastic load balancer and HAProxy).
My setup is as follows:
C# client -> HAProxy --> (SignalR Host 1 or SignalR Host 2)
The HAProxy is configured to roundrobin with cookies to ensure session stickiness
balance roundrobin
cookie SERVERID insert indirect nocache
When I have a single SignalR host behind the proxy (using Long Polling or Server Send Event) everything works fine. I can connect, invoke methods and handle callbacks.
As soon as I add a 2nd SignalR server things start to go poorly. I can connect fine and the connections properly load balance. I can send messages and they properly stick to the server. The problem is that callbacks just never make it back to my client through the proxy.
What is perplexing is this works fine with a single host configured on the load balancer.
Another note: I am not looking to scale out SignalR with a backplane. My signalr hosts don't need to know about each other or care about clients connected. In my architecture SignalR is the frontend to an application layer tier that handles communication service wide. I am essentially using Signlar to support push notifications from the application.
Thoughts?
I figured this out...
It turns out the problem was I wasn't handling the sticky session properly. Specifically, I wasn't associating the backend server cookie that the load balancer creates with my hub connection. The result is that the keep-alive was coming from one host where the other host was getting all the messages from the client so my client was effectively timing out silently. I enabled all the System.Diagnostics from signalr to figure this out.
I never figured out how to handle the stickiness during the connection process (probably creating a new persistentconnection class and handling connection messages). Instead I did it as part of a login process that is using REST calls. I retrieve the cookie from those calls and add that to the cookie container of the hubconnection and the sessions properly stick.
Update: Here is how you set the cookie in the hub connection
std::unordered_map<utility::string_t, utility::string_t> ConnectionHeaders;
ConnectionHeaders[U("Cookie")] = <INSERT COOKIE>
m_HubConnection->set_headers(ConnectionHeaders);
Thanks
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With