aspnet / SignalR

[Archived] Incredibly simple real-time web for ASP.NET Core. Project moved to https://github.com/aspnet/AspNetCore
Apache License 2.0
2.38k stars 448 forks source link

Server Timeout in JavaScript Client doesnt work as expected #2557

Closed ottohak closed 6 years ago

ottohak commented 6 years ago

Hi guys,

I am currently developing an internal application that needs to know when the connection to my SignalR server is lost. My goal is to react to a lost connection in up to 3 seconds.

So I set the serverTimeoutInMilliseconds to 3000 and the 'KeepAliveInterval' to TimeSpan.FromSeconds(1).

But this doesn't work as expected. For a test I send every second a message to the client, when I walk far enough away from my WiFi access point my Surface stops getting messages for 20+ seconds and then I am getting a onclose event.

If test this with my Android Phone running Chrome the onclose message is almost immediately fired when the signal is lost.

Maybe this this the way Windows handles lost network connections, but if I set the serverTimeoutInMilliseconds this shouldn't be a problem, right?

Thanks for this great project!

Please include as much of the following as you can in your bug report

When in doubt, feel free to file the issue, we're happy to help answer questions. We also suggest using the asp.net-core-signalr tag on StackOverflow to ask questions.

BrennanConroy commented 6 years ago

The HAR file you gave didn't complete the handshake request so it's not even running the code that makes use of serverTimeoutInMilliseconds. Could you try your scenario again but collect logs from a connection that actually connects?

ottohak commented 6 years ago

Okay, I hope the .har file is complete now. SecondTry.txt

This is the way I connect to the SignalR Server: https://github.com/ottohak/SignalR-Test/blob/master/src/app/app.component.ts

Edit: Firefox .har file: Archive 18-06-29 10-07-14.txt

BrennanConroy commented 6 years ago

Those HAR files are basically the same as the first one.

Lets try something different. Could you turn on logging on the javascript client https://github.com/aspnet/SignalR/wiki/Diagnostics-Guide#javascript-client-logging

Also, it would be nice to see how you are sending messages every second to the client from the server, and where does the client receive those messages?

analogrelay commented 6 years ago

One problem, which I should update the Diagnostics Guide to note, is that it looks like the browser dev tools don't include WebSocket frames in the network traces. You could try using Fiddler to get more detailed traces. Having the extra logging @BrennanConroy mentioned is also very useful as it will tell us what's going on in the client when it terminates the connection.

ottohak commented 6 years ago

Chrome Console Log: Log Traces.txt Fiddler Traces: Traces.saz.txt I hope I used Fiddler the right way, I wasn't sure what to look for.

@BrennanConroy I added the code how I receive the messages: https://github.com/ottohak/SignalR-Test/blob/master/src/app/app.component.ts#L37 This is basically how I send these messages:

signalHub.Clients.Clients(clients).SendAsync("Event", clientMessageData.Data);

Edit: This is how I added SignalR to my Server:

services.AddSignalR(options =>
{
  options.KeepAliveInterval = TimeSpan.FromSeconds(1);
});
BrennanConroy commented 6 years ago

I tried a simple test on a windows machine and couldn't repro. Although instead of walking away from a WIFI connection I SIGKILLed the server process which the OS might still try to gracefully close client connections.

ottohak commented 6 years ago

Yeah, to easily reproduce this issue I used a Surface Ethernet Adapter (https://www.microsoft.com/en-us/p/surface-usb-30-gigabit-ethernet-adapter/8xn9fqvzbvq0?activetab=pivot:techspecstab).

When I disconnect the USB Plug the Connection is lost immediately. Disabling the Network Connection in the Network Settings of Windows was always an immediate Connection lose (I think this happens when the USB Plug is disconnected).

But when I remove the Ethernet cable the connections waits 20 Seconds.

BrennanConroy commented 6 years ago

Perfect, I can repro this when unplugging the ethernet cord.

I'll investigate some more, but it looks like the timeout is being called within the 3 seconds, it might be the Websocket close that takes so long.

BrennanConroy commented 6 years ago

WebSocket.close() is taking 18+ seconds by itself and we call the connections onclose callback in the WebSocket.onclose event.

We can consider calling the callback in the close method on server timeouts to alert the user sooner.

BrennanConroy commented 6 years ago

Fixed via https://github.com/aspnet/SignalR/commit/53ceaf1b2c29aaa22a0c039609e2b34e27120396