SignalR与IIS 10和ARR 3.0 [英] SignalR with IIS 10 and ARR 3.0

查看:199
本文介绍了SignalR与IIS 10和ARR 3.0的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我们的Visual Studio开发机器前面使用ARR 3.0作为反向代理时,我们无法使SignalR正常工作。连接已成功建立,但建立连接后应从SignalR服务器发送的初始帧永远不会发送,事实上,不能发送任何帧,这会导致客户端丢弃WebSocket连接。总而言之,websocket连接可以建立,但不能传输帧。



MVC应用程序在没有反向代理的情况下工作。



我们在以下主题中尝试了所有建议的解决方案:






  • connect-request的屏幕截图。



    编辑1



    似乎正在发送连接帧但是在路上失败了。通过Wireshark在环回时可以看到它。





    编辑2



    当我没有在网址上附加后缀时,SignalR似乎与ARR一起使用。换句话说:




    解决方案

    所以,我们设法解决了这个问题,我们挖掘了潜在的原因,以便能够清楚地再现问题。它与重写完成的顺序有关,我们所做的是我们在ASP.NET MVC应用程序中创建了一个帮助器方法,如果来自orginated请求的HTTP头包含我们的重写路径,它将重写输入参数URL后缀。

      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;
    }
    }
    返回网址;
    }
    }

    我们将此方法用于SignalR的设定网址集线器/连接如下:

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

    结果将是$ .connection.hub.url ='@ RouteHelper.Url(/ portal / signalr)'



    很容易认为这会产生与创建出站重写规则相同的结果,该规则将执行此更改,但这不正确。



    从代理返回客户端的响应将是相同的,但代理和后端网络服务器之间的通信将发生故障。



    相反,我们为此创建了一个出站规则,如下所示:

     < rule name =SignalRReverseProxySignalRHubsUrl > 
    < match filterByTags =Nonepattern =connection.hub.url。* =。* ['\& quot;](。*)['\& quot;]/> ;
    < action type =Rewritevalue =connection.hub.url =& quot; / portal {R:1}& quot; />
    < / rule>

    我无法解释导致SignalR帧的反向代理和后端Web服务器之间发生的内部情况不要到达,但我可以确认所有URL重写都需要在代理处完成,并且模拟相同重写的应用程序中的逻辑将无法正常工作,至少不是以上述方式。


    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:

    解决方案

    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.

    这篇关于SignalR与IIS 10和ARR 3.0的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆