SignalR长轮询在5秒内断开

时间:2015-10-01 08:50:44

标签: .net asp.net-mvc signalr

我的应用程序正在公司网络(丑陋的代理和东西)下工作。它不能很好地工作。我希望使用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秒)。并且这种模式一再重复。那太奇怪了。

3 个答案:

答案 0 :(得分:5)

背景

根据Asp.net

  

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

     

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

Troubleshooting

请注意 SignalR 2.1为长轮询引入了保持活动。如果某些事情干扰了分块的HTTP响应,这可能会有问题。如果您想disable keepalive功能,请将KeepAlive设置为null Keepalive功能自动disabled用于长轮询传输。

如果您是using a Self-Host,请使用以下 3 args

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

作为支持长期轮询的保持活动“喜欢”功能的不同替代方法,请创建服务器方法名称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); 
    }
});

我希望有用。

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

似乎这种行为是由SignalR 2.1中的错误引起的。报告了类似的错误:fiddle所以我们将SignalR降级到2.0.3,这种行为消失了。