【问题标题】:signalR Core + ARR3 Reverse Proxy: Handshake TimeoutssignalR Core + ARR3 反向代理:握手超时
【发布时间】:2022-01-21 02:32:59
【问题描述】:

我在 docker 环境中使用 .net core 3.1,指向安装了 ARR 的 IIS 反向代理。

更新

我设法让重写运行。 BNut,因为我不知道它为什么会这样工作,所以我无法回答这个问题。 我将重写规则从 localhost: 更改为 127.0.0.1: 现在握手有效。但它似乎仅适用于 ServerSentEvents 的 websocket 协议。

Error: Failed to start the transport 'WebSockets': Error: WebSocket failed to connect. The connection could not be found on the server, either the endpoint may not be a SignalR endpoint, the connection ID is not present on the server, or there is a proxy blocking WebSockets. If you have multiple servers check that sticky sessions are enabled.

但是已经安装了 Websockets。我正在使用 ARR3。 所以对我来说最后两个问题是: 为什么它与 IP 而不是 localhost 一起工作? (下面的完整配置) 为什么安装了WS还是报这个错误?

完全重写配置:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <urlCompression doStaticCompression="false" doDynamicCompression="false" />
        <rewrite>
            <rules>
                <rule name="ReverseProxyInboundRule1" stopProcessing="true">
                    <match url="wss://(.*)" />
                    <action type="Rewrite" url="wss://127.0.0.1:3101/{R:1}" />
                </rule>
                <rule name="ReverseProxyInboundRule2" stopProcessing="true">
                    <match url="(.*)" />
                    <action type="Rewrite" url="https://127.0.0.1:3101/{R:1}" />
                </rule> 
            </rules>
            <outboundRules>
                <rule name="ReverseProxyOutboundRule1" preCondition="ResponseIsHtml1">
                    <match filterByTags="A, Form, Img" pattern="^http(s)?://127.0.0.1:3101/(.*)" />
                    <action type="Rewrite" value="http{R:1}://sub.example.com/{R:2}" />
                </rule>
                <preConditions>
                    <preCondition name="ResponseIsHtml1">
                        <add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
                    </preCondition>
                </preConditions>
            </outboundRules>
        </rewrite>
    </system.webServer>
</configuration>

编辑

感谢张小龙,我找到了问题的根源,但仍然不知道如何解决它。

我有一个通过 docker compose 在 Windows 服务器上运行的 docker 环境。 在那里,我将 IIS10 与 UrlRewrite 和 ARR3 以及 .net core 3.1 应用程序和 signalR 核心一起使用。 作为客户,我使用@microsoft/signalr 的打字稿版本(最新) 由于某些原因,我不知道连接是否正常,但握手呼叫以超时结束。 我在网上查看了一些解决方案并应用了这个:

  1. 为 wss:// 和 ws:// 添加了 URL 重写入站规则
  2. 增加了 signalR 的超时时间
  3. 在 ARR 中配置响应缓冲区(见下图)
  4. 启用失败的请求跟踪

docker env 与启用了 ARR 和 Websockets 功能的 IIS 在同一台服务器上运行。

Web-App 容器公开端口 6652,将其映射到 docker 容器中的端口 443。

我的重写规则定义如下:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <urlCompression doStaticCompression="false" doDynamicCompression="false" />
        <rewrite>
            <rules>
                <rule name="WS reverse proxy" stopProcessing="true">
                    <match url="ws://devlocal.example.com" />
                    <conditions>
                        <add input="{CACHE_URL}" pattern="^(.+)://" />
                    </conditions>
                    <action type="Rewrite" url="{C:1}://127.0.0.1:6652" />
                </rule>
                <rule name="WSS reverse proxy" stopProcessing="true">
                    <match url="wss://devlocal.example.com" />
                    <conditions>
                        <add input="{CACHE_URL}" pattern="^(.+)://" />
                    </conditions>
                    <action type="Rewrite" url="{C:1}://127.0.0.1:6652" />
                </rule>

                <rule name="_Inbound_devlocal.example.com.com" stopProcessing="true">
                    <match url="(.*)" />
                    <action type="Rewrite" url="{C:1}://localhost:6652/{R:1}" logRewrittenUrl="true" />
                    <conditions logicalGrouping="MatchAny">
                        <add input="{CACHE_URL}" pattern="^(.+)://" />
                        <add input="{HTTP_HOST}" pattern="^devlocal\.example.com\.com$" />
                    </conditions>
                </rule>

            </rules>
            <outboundRules>
                <rule name="_Outboundund_devlocal.example.com.com" stopProcessing="true">
                    <match filterByTags="A, Form, Img, Link, Script" pattern="^http(s)?://localhost:6652/(.*)" />
                    <action type="Rewrite" value="http{R:1}://devlocal.example.com.com/{R:2}" />
                </rule>
            </outboundRules>
        </rewrite>
    </system.webServer>
</configuration>

SignalR 配置为:

services.AddSignalR(hubOptions =>
           {
               hubOptions.ClientTimeoutInterval = TimeSpan.FromSeconds(240);
               hubOptions.HandshakeTimeout = TimeSpan.FromSeconds(120);
               hubOptions.KeepAliveInterval = TimeSpan.FromSeconds(60);
               hubOptions.EnableDetailedErrors =  true;
               hubOptions.MaximumReceiveMessageSize = 200;
               hubOptions.StreamBufferCapacity = 300;
           });
// Mappig hub  like:

app.UseEndpoints(api =>
            {
                api.MapControllers();
                api.MapHub<CommentsHub>("/sockR/hub");
            }
);

ARR 配置:

signalR 客户端的跟踪日志显示它的握手调用以超时结束:

[2022-01-13T18:29:07.232Z] Information: Normalizing '/sockR/hub' to 'https://devlocal.example.com/sockR/hub'.
Utils.js:151 [2022-01-13T18:29:07.233Z] Debug: Starting HubConnection.
Utils.js:151 [2022-01-13T18:29:07.233Z] Debug: Starting connection with transfer format 'Text'.
Utils.js:147 [2022-01-13T18:29:07.342Z] Information: WebSocket connected to wss://devlocal.example.com/sockR/hub.
Utils.js:151 [2022-01-13T18:29:07.342Z] Debug: The HttpConnection connected successfully.
Utils.js:151 [2022-01-13T18:29:07.342Z] Debug: Sending handshake request.
Utils.js:147 [2022-01-13T18:29:07.342Z] Information: Using HubProtocol 'json'.
... After 3 minutes:
ERROR Error: Uncaught (in promise): Error: Server timeout elapsed without receiving a message from the server. Error: Server timeout elapsed without receiving a message from the server.

有什么方法可以调试为什么请求以超时结束?奇怪的是,我在服务器上也有一个 jira 实例。也通过具有相同设置的反向代理绑定,并且那里的 WSS/WS 调用不会失败。

【问题讨论】:

  • 我认为你可以使用失败的请求跟踪来跟踪请求。检查 ARR 是否将请求正确转发到后端服务器。然后你可以知道超时发生在哪里,ARR 或后端服务器。
  • 启用失败请求跟踪,但日志文件夹为空。应用程序可以写入我的机器上的文件夹
  • 我的意思是你可以在 ARR 服务器上启用它,这样它就会显示它是否成功转发请求。如果文件夹为空,则表示它没有收到请求。
  • 我的 docker env 与 iis 在同一台服务器上运行。计划是从 iis 站点(例如 sub.mydomain.com)反向代理到我在同一机器上的 docker 容器中运行的站点,因为计划是将来切换到 azure 或 aws。通过 http/https 的所有请求都可以正常工作,并且请求主机也被正确重写。我在控制台中看到的是握手似乎在集线器连接中起作用......只有在集线器上下文发送新消息时才会引发此错误。
  • 更新似乎超时也发生在连接后。所以请求没有通过的理论是正确的。来自 signalR 的调试日志只是错误地说“已连接”。但是通过我上面的配置,wss 调用也应该通过。还是我的配置中遗漏了什么?

标签: asp.net-core iis signalr asp.net-core-signalr arr-3.0


【解决方案1】:

显然它现在可以通过删除: 启动.cs

app.UseWebSockets();

在将我的重写配置更改为:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <urlCompression doStaticCompression="false" doDynamicCompression="false" />
        <rewrite>
            <rules>
                <rule name="ReverseProxyInboundRule1" stopProcessing="true">
                    <match url="wss://(.*)" />
                    <action type="Rewrite" url="wss://127.0.0.1:3101/{R:1}" />
                </rule>
                <rule name="ReverseProxyInboundRule2" stopProcessing="true">
                    <match url="(.*)" />
                    <action type="Rewrite" url="https://127.0.0.1:3101/{R:1}" />
                </rule> 
            </rules>
            <outboundRules>
                <rule name="ReverseProxyOutboundRule1" preCondition="ResponseIsHtml1">
                    <match filterByTags="A, Form, Img" pattern="^http(s)?://127.0.0.1:3101/(.*)" />
                    <action type="Rewrite" value="http{R:1}://sub.example.com/{R:2}" />
                </rule>
                <preConditions>
                    <preCondition name="ResponseIsHtml1">
                        <add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
                    </preCondition>
                </preConditions>
            </outboundRules>
        </rewrite>
    </system.webServer>
</configuration>

【讨论】:

    猜你喜欢
    • 2015-01-15
    • 1970-01-01
    • 2016-11-17
    • 1970-01-01
    • 2016-03-19
    • 1970-01-01
    • 1970-01-01
    • 2019-02-04
    • 2023-01-27
    相关资源
    最近更新 更多