3

I am trying to change the hub connection url in signalR so that all requests go through my custom load balancer.

The load balancer then redirects to original signalR web application and gives the response.

For this i am trying to create a new hub connection by changing the url like this

var signalR = $.signalR;
signalR.hub = $.hubConnection("http://localhost:64071/LoadBalancer.Web/NotificationWeb/signalr", { useDefaultPath: false });

The signalR tries to connect to this URL and in the negotiate request returns this response

{ "Url":"/WE.abcd.Web/signalr", "ConnectionToken":"raYdZtwHWMP50fYIxa4MxRtR8xZAmUhhdlXreYVlB3Meo+2VeZSk4wMEdbkCbVEAzo/+gFyNofqV ......

Then as you can see in the response, the URL contains original URL (i.e. WE.abc.web) so the communications happens directly to WE.abcd.Web instead of passing through my Load Balancer. Web even after overriding the URLs.

How can i force the negotiate request to return me the LoadBalancer.Web URL instead of original URL?

PravinS
  • 2,640
  • 3
  • 21
  • 25
  • This is what the server does to come up with this url: https://github.com/SignalR/SignalR/blob/master/src/Microsoft.AspNet.SignalR.Core/PersistentConnection.cs#L504. Not sure why is it mportant in your case - the client does not use this url anyways. – Pawel Jun 01 '15 at 21:53
  • In my case the client is using this Url for subsequent connect request This is next request after negotite http://localhost:64071/we.abcd.web/signalr/connect?...... As you can see in the Url again the original site name comes. On client side nowhere I have given this url, so it seems that it is taking from response of negotiate request – Kuldeep Bhatnagar Jun 02 '15 at 04:40
  • 1
    @PravinS - I tried to change code you have pointed out. Instead of Request localpath, I am now using the Referer path. Now is working fine. Here is the changed code var referer = context.Request.Headers.Get("Referer"); var originateUrl = string.IsNullOrEmpty(referer) ? context.Request.LocalPath : new Uri(referer).LocalPath; var payload = new { Url = originateUrl.Replace("/negotiate", ""), ......................... } Any reason why we have used Request.LocalPath? – Kuldeep Bhatnagar Jun 02 '15 at 11:46
  • @KuldeepBhatnagar did you end up building your own SignalR library after your change? or did you only create sub-classes for the `HubDispatcher`? I'm facing the same problem and I'm trying to avoid modifying SignalR source code... – Adolfo Perez Sep 26 '15 at 01:53

1 Answers1

0

I think as long as SignalR is generating negotiate response URL using Request.LocalPath only solution is to load balancer modify negotiate response (rewrite URL) before returning it back to client. That's how reverse proxies work.

It should be possible to do that without changing load balancer code just using IIS URL Rewrite functionality

Sidenote: I don't know nothing about your requirements\production environment but if load balanced sites (hosting SignalR) are accessible from clients (not hidden behind firewall\proxy), described behavior is totally fine. As long as load balancer is balancin negotiate requests between all servers, it does't matter that subsequent connection request bypass load balancer - clients are still balanced. + less trouble as you don't need to balance Web sockets connections...

Community
  • 1
  • 1
Michal Levý
  • 33,064
  • 4
  • 68
  • 86
  • I am not sure the load balancer can/should change anything in response. It may change the request/response headers but it should return the response as it is. The url is part of the response and load balancer is generic and we cannot have some special logic inside loadbalancer – Kuldeep Bhatnagar Jun 02 '15 at 11:22
  • I didn's say your code should do response modification. It can be done by using IIS URL Rewrite functionality configured for load balancer site... – Michal Levý Jun 02 '15 at 12:13
  • Yes, I agree on using URL rewrite functionality. I will try to configure that. Thanks for the help.
    Now my second issue is getting ""The ConnectionId is in the incorrect format." in case of polling request in load balanced environment.
    It is given in this post http://stackoverflow.com/questions/30573063/does-signalr-backplane-shares-connections-also
    can you please help in solving this issue too
    – Kuldeep Bhatnagar Jun 03 '15 at 04:35