当客户端在高延迟连接后面时,SignalR无法工作

Fre*_*ard 2 latency azure websocket signalr

我正在编写一个严重依赖SignalR的应用程序.最近,我不得不选择卫星ISP提供商.这带来了一个大问题,看起来卫星的700毫秒延迟似乎给SignalR带来了困难.我可以测试延迟大约50ms的4G网络,那里的工作效果很好.我打开了客户端跟踪,问题是它何时尝试加入集线器.

以下是服务器上用于Join方法的代码:

public Task Join(string groupName) { var hub = GlobalHost.ConnectionManager.GetHubContext("myHub"); var results = hub.Groups.Add(Context.ConnectionId, groupName); return results; }

在日志中,我看到:

[23:41:14 GMT-0400 (Eastern Daylight Time)] SignalR: Client subscribed to hub 'myHub'. jquery.signalR-2.1.1.min.js:8
[23:41:14 GMT-0400 (Eastern Daylight Time)] SignalR: Negotiating with '/signalr/negotiate?clientProtocol=1.4&connectionData=%5B%7B%22name%22%3A%22myHub%22%7D%5D'. jquery.signalR-2.1.1.min.js:8
[23:41:15 GMT-0400 (Eastern Daylight Time)] SignalR: Connecting to websocket endpoint 'ws://myurl/signalr/connect?transport=webSockets&clientProtocol=1.4&connectionToken=myToken&connectionData=%5B%7B%22name%22%3A%22myHub%22%7D%5D&tid=10'. jquery.signalR-2.1.1.min.js:8
[23:41:30 GMT-0400 (Eastern Daylight Time)] SignalR: Websocket opened. jquery.signalR-2.1.1.min.js:8
[23:41:30 GMT-0400 (Eastern Daylight Time)] SignalR: webSockets transport selected. Initiating start request. jquery.signalR-2.1.1.min.js:8
[23:41:31 GMT-0400 (Eastern Daylight Time)] SignalR: The start request succeeded. Transitioning to the connected state. jquery.signalR-2.1.1.min.js:8
[23:41:31 GMT-0400 (Eastern Daylight Time)] SignalR: Now monitoring keep alive with a warning timeout of 13333.333333333332 and a connection lost timeout of 20000. jquery.signalR-2.1.1.min.js:8
[23:41:31 GMT-0400 (Eastern Daylight Time)] SignalR: Invoking myHub.Join jquery.signalR-2.1.1.min.js:8
[23:41:31 GMT-0400 (Eastern Daylight Time)] SignalR: Invoking myHub.Join
Run Code Online (Sandbox Code Playgroud)

它停在那里.当我尝试4G连接(即低延迟)时,我得到回调日志:

[23:41:31 GMT-0400 (Eastern Daylight Time)] SignalR: Invoked myHub.Join jquery.signalR-2.1.1.min.js:8
[23:41:31 GMT-0400 (Eastern Daylight Time)] SignalR: Invoked.myHub.Join
Run Code Online (Sandbox Code Playgroud)

我正在利用Azure Service Bus来处理消息传递部分.

有人有什么想法吗?尝试使用Signalr配置设置,没有运气.

事实上它对我不起作用并不是什么大问题,我对VPN也有同样的问题,但我有一种感觉,如果我找不到解决办法,我会让很多用户失望......就像来自印度的延迟较高的用户

Fre*_*ard 6

在做了一些挖掘之后,我能够发现问题出在websockets传输上.我激发了自己对这篇文章的启发, 并提出了以下建议:

var latency = ping();
console.log('latency: ' + latency);

if (latency > 500) {
   $.connection.hub.start({ transport: ['foreverFrame', 'serverSentEvents', 'longPolling'] }).done(StartHub);
} else {
    $.connection.hub.start().done(StartHub);
}
Run Code Online (Sandbox Code Playgroud)

这是ping的代码,灵感来自这篇文章

function ping() {
var data;
var startTime;
$.ajax({
    url: 'ping.html?v=' + Math.random(), //ping.html is a dummy html page
    async: false,
    beforeSend: function () {
        startTime = new Date();
    },
    complete: function (jqXHR, textStatus) {
        data = (new Date()) - startTime;
    }
});
return data;
Run Code Online (Sandbox Code Playgroud)

}

这允许回调被触发,即我现在看到日志中的"被调用".但是,我时不时地得到超时.

将信号器设置更改为:

GlobalHost.Configuration.TransportConnectTimeout = TimeSpan.FromMinutes(5);
GlobalHost.Configuration.ConnectionTimeout = TimeSpan.FromMinutes(5);
GlobalHost.Configuration.KeepAlive = null;
Run Code Online (Sandbox Code Playgroud)

我会对上面的内容进行微调,但它现在已经成功了.

我仍然需要做更多的测试,但它看起来非常有前景.当我使用4G连接时,它使用websockets,当我使用卫星连接时,它使用另外3个中的一个.

不确定这是否是最佳解决方案,但它确实符合我的需求.我想知道在决定使用哪种传输时,是否应将类似的内容放入SignalR代码中.可能有更好的方法来查找延迟,但概念是存在的......