New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 706002 link

Starred by 13 users

Issue metadata

Status: Assigned
Owner:
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Linux , Mac
Pri: 3
Type: Feature

Blocked on:
issue 865002


Show other hotlists

Hotlists containing this issue:
Nice-to-haves-for-Project-V


Sign in to add a comment

Implement client-initiated WebSocket ping-pong to detect network errors

Reported by l...@nri.pl, Mar 28 2017

Issue description

UserAgent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.110 Safari/537.36

Steps to reproduce the problem:
1. open page with new WebSocket()
2. wait for connect ws.onopen
3. disable network interface or pull the plug

What is the expected behavior?
I was expecting the ws.onclose event to be executed.
ws.onclose = function() { console.log("disconnected") }

What went wrong?
ws.onclose event was not fired up after the connection was broken.

Did this work before? No 

Does this work in other browsers? Yes

Chrome version: 57.0.2987.110  Channel: stable
OS Version: Fedora
Flash Version: 

The same issue occurs in version 59 on Linux and Windows.
On FireFox it works as expected.

Of course, the issue only occurs when the connection is suddenly broken. If the server sends TCP Close, then Chromium responds properly by firing the event ws.onclose.
 
Components: -Blink>Network Blink>Network>WebSockets
This is how linux works.  You can see this for yourself, run "telnet google.com 80" and then pull your network cable.  Telnet's TCP connection isn't closed when the network cable is unplugged.
Labels: TE-NeedsTriageHelp

Comment 3 by l...@nri.pl, Mar 30 2017

I know how TCP works.
WebSocket has ping-pong (keepalive), to solve this problem.
https://tools.ietf.org/html/rfc6455#section-5.5.2

FireFox has it.
I would like the Chromium to have it too.
Cc: tyoshino@chromium.org ricea@chromium.org yhirano@chromium.org
Labels: -Type-Bug -Hotlist-Interop Type-Feature
Status: Untriaged (was: Unconfirmed)
Summary: Implement client-initiated WebSocket ping-pong to detect network errors (was: Websocket don't close on network disconnected)
ricea@, tyoshino@, what do you think about supporting a client-initiated ping-pong?

Comment 5 by ricea@chromium.org, Apr 5 2017

It looks like Chrome uses SO_KEEPALIVE at the TCP/IP level on Desktop platforms with a 45 second interval. So we should detect disconnect within 45 (90?) seconds.

According to this issue: https://bugzilla.mozilla.org/show_bug.cgi?id=444328 Firefox does too. It appears that Firefox uses keepalives every 10 seconds for the first 60 seconds of idle time, so that may explain the observed difference.

It's much more expensive to ping at the WebSocket level than at the TCP/IP level, so I'd prefer to avoid it.

Comment 6 by l...@nri.pl, Apr 5 2017

Keepalives at the TCP/IP level is fine.
I do not see the need for an additional API in JS.
It is important to ws.onclose event is triggered.

Currently Chromium detects offline.
window.addEventListener('offline', 
IMHO it should escalate ws.onclose 
(other than localhost)


Comment 7 by ricea@chromium.org, Apr 5 2017

I've heard that offline detection is not 100% reliable, which worries me. I don't want Chrome to close perfectly good connections if we're not actually offline.

I'd also like to be robust in the face of temporary network drops. Sometimes my devices lose wifi then a moment later they're fine.
> I've heard that offline detection is not 100% reliable, which worries me. I don't want Chrome to close perfectly good connections if we're not actually offline.

I think the offline detection is actually pretty accurate, and it is very conservative about declaring the device offline, in other words it only declares the device offline when there is no chance of network activity succeeding.  That said the rest of the networking stack never cancels active requests when the device is detected to be offline, we just flush idle socket pools and DNS cache.

One option is send a ping packet when the device is detected to be offline.

Comment 9 by ricea@chromium.org, Apr 6 2017

> One option is send a ping packet when the device is detected to be offline.

This is attractive. We'd have to rate limit it.

I wonder if we'd find buggy servers that don't respond to pings? I suppose the answer to that is to use UMA.

Comment 10 by ricea@chromium.org, Apr 11 2017

Status: Available (was: Untriaged)
We can also use the UMA to determine a good timeout value between sending the ping and giving up on receiving a response. It would be good to configure this dynamically based on the "real" RTT but I think that would mean sending one or more pings after the handshake to measure it, which we might not want to do.
I'm interested to see the network disconnect and network switch like wifi switch not socket server response. 

If i disconnect wifi in MacOS 10.11
Chrome 58, ws disconnect does not happen at all
Firefox, ws disconnect triggers in 10 sec.
Safari disconnects in immediately

Just try below code in Chrome console to see the behaviour.
var connection  = new WebSocket('wss://echo.websocket.org')
connection.onopen = function () {
console.log('onopen');
};
connection.onerror = function (error) {
  console.log('WebSocket Error ' + error);
};
connection.onmessage = function (e) {
  console.log('Server: ' + e.data);
};
connection.onclose = function (e) {
  console.log('onclose: ' ,e);
};

Detect disconnect in 45-90 sec is not happening!
Labels: -Pri-2 OS-Mac Pri-3
Owner: ricea@chromium.org
I just tried this on OS X 10.12.4 and it did eventually disconnect after 18 minutes. I need to do more investigation. Temporarily assigning to me.
Project Member

Comment 13 by sheriffbot@chromium.org, May 2 2018

Labels: Hotlist-Recharge-Cold
Status: Untriaged (was: Available)
This issue has been Available for over a year. If it's no longer important or seems unlikely to be fixed, please consider closing it out. If it is important, please re-triage the issue.

Sorry for the inconvenience if the bug really should have been left as Available.

For more details visit https://www.chromium.org/issue-tracking/autotriage - Your friendly Sheriffbot
Labels: -Hotlist-Recharge-Cold
Status: Assigned (was: Untriaged)
Blockedon: 865002
Blocked on issue 865002 as we can't really start sending Pings while Chrome's built-in WebSocket server doesn't support them.
Why is the websocket client ping implementation blocked by the server implementation? Do I have a misunderstanding that they shouldn't have to do with each other? They are separate implementations, no?

I mean, as a websocket client, I can connect to all kinds of websocket servers, not just Chrome-based ones, if that would be the root cause of the blockage. I connect to python based websocket servers that support protocol ping=pongs, they even send it at configured intervals.

Websocket protocol ping/pongs are part of the protocol implementation, many server has it. If someone could enlighten me why #865002 is a blocker for this?
#16 The DevTools protocol uses the WebSocket server built in to Chrome. Which means that if Chrome's WebSocket client sends something that Chrome's WebSocket server doesn't understand, it could break DevTools. We can't break DevTools.
#17 fair enough.

Still, I find it a bummer to block everyone else connecting to other servers than chrome based ones.

Can't it be made optional somehow? I have nothing against exposing it to the developers, so they would be able to set it for themselves manually, should they need it. It could be turned off by default.

I just had a look at Firefox 62.0.3, and it's a configuration setting 'network.websocket.timeout.ping.request' over there (however it's also not exposed as a JS API), and it's set to 0 per default. So it's disabled over there, but can be overridden by administrators.

Exposing it as a JS API, even if namespaced would be beneficial for programmers like me who'd like to use it.

#18 We try to avoid adding Chrome-only APIs. If people used the APIs unconditionally, their sites wouldn't work in other browsers and it would be harmful to the web ecosystem.

Adding a standard API is possible, but it would take a long time (much longer than just fixing the bug in our server!), and there's no-one available to work on it.

Chrome's philosophy on flags is different from Firefox. We mostly avoid having features behind a flag long term, as we cannot support non-standard configurations.

Sorry for the disappointing response.

Sign in to add a comment