【问题标题】:SignalR long-polling is disconnected in 5 secondsSignalR 长轮询在 5 秒后断开
【发布时间】:2015-12-29 06:04:09
【问题描述】:

我的应用程序在公司网络下运行(丑陋的代理和东西)。而且效果不是很好。我希望使用 https 会有所帮助,但它没有。这是我在日志中看到的一个奇怪的模式:

[14:13:32 GMT+0600 (N. Central Asia Standard Time)] SignalR: Client subscribed to hub 'modemshub'.
[14:13:32 GMT+0600 (N. Central Asia Standard Time)] SignalR: Negotiating with '/signalr/negotiate?clientProtocol=1.5&connectionToken=6aktO0sramoQKhQ9DC7Cs7EbXMUou8LooQRxfup4R0oZCHpBmWBFjyLup%2F3wJLloR8GtJEiUk10YOZJBaSqN8aiGAfXRR4G9hujTFTyiJiz%2FyJ4oMlBIdxqeCc5anI6k&connectionData=%5B%7B%22name%22%3A%22modemshub%22%7D%5D'.
[14:13:32 GMT+0600 (N. Central Asia Standard Time)] SignalR: longPolling transport starting.
[14:13:32 GMT+0600 (N. Central Asia Standard Time)] SignalR: Opening long polling request to 'https://example.com/signalr/connect?transport=longPolling&clientProt…rlCzGHl5kVLClT5ex8&connectionData=%5B%7B%22name%22%3A%22modemshub%22%7D%5D'.
[14:13:33 GMT+0600 (N. Central Asia Standard Time)] SignalR: Long poll complete.
[14:13:33 GMT+0600 (N. Central Asia Standard Time)] SignalR: LongPolling connected.
[14:13:33 GMT+0600 (N. Central Asia Standard Time)] SignalR: longPolling transport connected. Initiating start request.
[14:13:33 GMT+0600 (N. Central Asia Standard Time)] SignalR: Opening long polling request to 'https://example.com/signalr/poll?transport=longPolling&clientProtoco…rlCzGHl5kVLClT5ex8&connectionData=%5B%7B%22name%22%3A%22modemshub%22%7D%5D'.
[14:13:33 GMT+0600 (N. Central Asia Standard Time)] SignalR: The start request succeeded. Transitioning to the connected state.
[14:13:38 GMT+0600 (N. Central Asia Standard Time)] SignalR: Long poll complete.
[14:13:38 GMT+0600 (N. Central Asia Standard Time)] SignalR: Stopping connection.
[14:13:38 GMT+0600 (N. Central Asia Standard Time)] SignalR: Fired ajax abort async = true.

所以连接已建立,5 秒后它被中​​止(而 ConnectionTimeout 等于 110 秒)。这种模式一次又一次地重复。这很奇怪。

【问题讨论】:

    标签: .net asp.net-mvc signalr


    【解决方案1】:

    背景

    根据Asp.net

    SignalR 使用传输 API 创建传输连接,传输 API 依赖于物理网络连接的存在来创建传输连接。当 SignalR 终止传输连接或传输 API 检测到物理连接中断时,传输连接结束。

    物理连接可能很慢或连接可能中断。根据中断时长等因素,传输连接可能会断开。 SignalR 然后尝试重新建立传输连接。有时传输连接 API 检测到中断并断开传输连接,SignalR 会立即发现连接丢失。在其他情况下,传输连接 API 和 SignalR 都不会立即意识到连接已丢失。 对于除长轮询之外的所有传输,SignalR 客户端使用名为 keepalive 的函数来检查传输 API 无法检测到的连接丢失。

    Troubleshooting

    请注意 SignalR 2.1 为长轮询引入了保持活动状态。如果某些东西干扰了分块的 HTTP 响应,这可能会出现问题。如果您想要disablekeepalive 功能,请将KeepAlive 设置为nullKeepalive 功能自动为disabled 用于长轮询 传输。

    如果您是 using a Self-Host,请改用以下 3 个参数

    GlobalHost.Configuration.ConnectionTimeout = new TimeSpan(0,0,110);
    GlobalHost.Configuration.DisconnectTimeout = new TimeSpan(0,0,30);
    GlobalHost.Configuration.KeepAlive = new TimeSpan(0,0,10);
    

    作为支持长轮询的“like”功能的不同替代方案,创建一个服务器方法,将其命名为Ping

    public class MyHub : Hub
    {
        public void Ping()
        {
        }
    }
    

    然后,在客户端创建一个间隔,您将在其中 Ping 服务器:

    var proxy = $.connection.myHub,
        intervalHandle;  
    ...
    $.connection.hub.disconnected(function() {
        clearInterval(intervalHandle);
    });  
    ...  
    $.connection.hub.start().done(function() {
        // Only when long polling
        if($.connection.hub.transport.name === "longPolling") {
            // Ping every 10s
            intervalHandle = setInterval(function() {
                // Ensure we're connected (don't want to be pinging in any other state).
                if($.connection.hub.state === $.signalR.connectionState.connected) {
                    proxy.server.ping().fail(function() {
                        // Failed to ping the server, we could either try one more time to ensure we can't reach the server
                        // or we could fail right here.
                        TryAndRestartConnection(); // Your method
                    });
                }
            }, 10000); 
        }
    });
    

    希望对你有用。

    【讨论】:

      【解决方案2】:

      假设Understanding and Handling Connection Lifetime Events in SignalR 中提供了提示,您可以在其中根据网络问题采用良好的解决方案来处理连接寿命。此外,在 SignalR 的问题中,我为您找到了以下解决方案,它也适用于长轮询。

      您可以在 ConfigurationManager 上设置 KeepAlive 属性,SignalR 将在指定的时间间隔发送一个空数据帧(基于传输)以保持连接处于活动状态(查看Allow host to specify keep alive times)。当前的超时机制使流协议没有什么不同。

      【讨论】:

        【解决方案3】:

        似乎这种行为是由 SignalR 2.1 中的错误引起的。报告了一个类似的错误:https://github.com/SignalR/SignalR/issues/3557 所以我们将 SignalR 降级到 2.0.3 并且这种行为消失了。

        【讨论】:

          猜你喜欢
          • 2023-03-29
          • 2012-10-11
          • 2013-07-16
          • 1970-01-01
          • 1970-01-01
          • 2017-11-30
          • 1970-01-01
          • 2012-04-04
          • 1970-01-01
          相关资源
          最近更新 更多