SignalR with IIS 10 and ARR 3.0

匿名 (未验证) 提交于 2019-12-03 10:24:21

问题:

We can't get SignalR to work when using ARR 3.0 as a reverse proxy in front of our Visual Studio development machine. The connection is successfully established but the initial frame that should be sent from the SignalR server once the connection is established is never sent, as a matter of fact, no frames can be sent, this causes the client to drop the WebSocket connection. To sum up, "the websocket connection can establish, but can't transfer frames."

The MVC app works without the reverse proxy.

We've tried all suggested solutions in the following threads:

Screenshot of "negotiate"-request.

Screenshot of "connect"-request.

EDIT 1

It appears that the connected-frame is being sent but fails down the road. It's visible through Wireshark on loopback.

EDIT 2

It appears that SignalR works with ARR when I'm not appending a suffix to the url. In other words:

回答1:

So, we managed to solve the matter in question and we dug down in the underlying cause to be able to reproduce the problem clearly. It has to do with the order in which rewriting is done, what we did was that we had created a helper method in our ASP.NET MVC application that would rewrite the input parameter URL if the HTTP headers from the orginated request contained our rewriting path suffix.

public static class RouteHelper {     public static string Url(string url)     {         string orginalUrl = HttpContext.Current?.Request.Headers["X-Original-URL"];         if (!string.IsNullOrEmpty(orginalUrl))         {             if (orginalUrl.StartsWith("/" + "portal", true, CultureInfo.InvariantCulture)                 || orginalUrl.StartsWith("portal", true, CultureInfo.InvariantCulture))             {                 url = "/" + "portal" + url;             }         }         return url;     } } 

We used this method to the set URL of the SignalR hub/connection as following:

$.connection.hub.url = '@RouteHelper.Url("/signalr")' 

The result would be $.connection.hub.url = '@RouteHelper.Url("/portal/signalr")'

It's easy to think that this would give the same result as creating an outbound rewrite rule that would do this changes but that's not correct.

The response that returns to the client from the proxy will be the same but the communication between the proxy and the backend webserver will malfunction.

Instead, we created an outbound rule for this, that looked like this:

<rule name="SignalRReverseProxySignalRHubsUrl">     <match filterByTags="None" pattern="connection.hub.url.*=.*['\&quot;](.*)['\&quot;]" />     <action type="Rewrite" value="connection.hub.url = &quot;/portal{R:1}&quot;" /> </rule> 

I can't explain what's happening internal between the reverse proxy and backend web servers that causes the SignalR frames not to arrive but I can confirm that all URL rewriting needs to be done at the proxy and logic in the application that simulates the same rewriting will not work properly, at least not in the way described above.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!