Reputation: 81
I am writing an app that relies heavily on SignalR. Lately, I had to go with a Satellite ISP Provider. This brought up a big issue, where it seems that the 700 ms latency with the Satellite is giving SignalR a hard time. I can test with the 4G network where the latency is around 50ms and things works just great there. I turned on the client tracing and the problem is when it tries to join a hub.
Here is the code on the server for the Join method:
public Task Join(string groupName)
{
var hub = GlobalHost.ConnectionManager.GetHubContext("myHub");
var results = hub.Groups.Add(Context.ConnectionId, groupName);
return results;
}
In the logs, I see:
[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
It stops there. When I try with the 4G connection (ie low latency), I get the callback logs:
[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
I am leveraging the Azure Service Bus to handle the messaging part.
Anybody has any idea? Tried to play with the Signalr configuration settings with no luck.
The fact that it does not work for me is not a big deal, I have the same issue with VPN, but I have a feeling that if I do not find a work around, I will let down a lot of users... like users from India where the latency is higher..
Upvotes: 2
Views: 2969
Reputation: 81
After doing some more digging, I was able to figure out that the issue was with the websockets transport. I inspired myself of this post and came up with the following:
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);
}
Here is the code for the ping, which was inspired from this post
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;
}
This allowed the callbacks to be fired, ie I was now seeing the "invoked" in the logs. However, I was getting timeouts every now and then.
Changed the Signalr settings to:
GlobalHost.Configuration.TransportConnectTimeout = TimeSpan.FromMinutes(5);
GlobalHost.Configuration.ConnectionTimeout = TimeSpan.FromMinutes(5);
GlobalHost.Configuration.KeepAlive = null;
I will fine tune the above, but it did the trick for now.
I still need to do some more testing, but it looks pretty promising. It uses websockets when I am with my 4G connections, and then one of the other 3 when I am using my satellite connection.
Not sure if this is the best solution, but it certainly suits my needs. I wonder if something like that should be put in the SignalR code when it decides which transport to use.. There might be a better way to find the latency, but the concept is there..
Upvotes: 6