This is an archived snapshot of W3C's public bugzilla bug tracker, decommissioned in April 2019. Please see the home page for more details.

Bug 13104 - Enable keepalive on WebSocket API
Summary: Enable keepalive on WebSocket API
Status: RESOLVED FIXED
Alias: None
Product: WebAppsWG
Classification: Unclassified
Component: WebSocket API (editor: Ian Hickson) (show other bugs)
Version: unspecified
Hardware: Other other
: P3 normal
Target Milestone: ---
Assignee: Ian 'Hixie' Hickson
QA Contact: public-webapps-bugzilla
URL: http://www.whatwg.org/specs/web-apps/...
Whiteboard:
Keywords:
: 14115 (view as bug list)
Depends on:
Blocks:
 
Reported: 2011-06-30 16:51 UTC by contributor
Modified: 2011-10-25 04:39 UTC (History)
7 users (show)

See Also:


Attachments

Description contributor 2011-06-30 16:51:56 UTC
Specification: http://dev.w3.org/html5/websockets/
Multipage: http://www.whatwg.org/C#top
Complete: http://www.whatwg.org/c#top

Comment:
1) ping(msg); //allow client to send server ping as per websocket spec
2) onpong(); //allow client to receive response of ping


Posted from: 65.5.190.254
User agent: Mozilla/5.0 (X11; Linux i686; rv:7.0a1) Gecko/20110630 Firefox/7.0a1
Comment 1 Adrian Bateman [MSFT] 2011-07-01 16:21:54 UTC
We don't think it's necessary to include API support for ping/pong, which is similar to TCP-level-like keepalives that can cross intermediaries. They are used to notify anyone on the path to the server and the server itself that the client is still alive.
 
It should be the job of the stack to keep your connection alive. The application may want to specify keepalive interval, but it should not need to handle this task itself.
Comment 2 Ian 'Hixie' Hickson 2011-07-08 20:04:37 UTC
What's the use case?
Comment 3 Iñaki Baz Castillo 2011-09-12 19:00:00 UTC
(In reply to comment #2)
> What's the use case?

In case the network connection goes down (for example the ADSL dies), the WebSocket client could not realize of it until it attempts to send a new WS frame (it happens sometimes because there is not a TCP disconnection).

By sending periodical WS Ping frames from client to server, the client could realize of the network issue in a reasonable time.

As a suggestion, the WS API could include an interval for sending Ping frames to the server:

    var myWebSocket = new WebSocket("ws://some-domain.com");
    myWebSocket.set_monitor_interval(120);
Comment 4 Joel Martin 2011-09-12 19:40:10 UTC
I can see a use for being able to turn on keepalive from the client. Maybe the interval should be left up to the browser (or at least the interval could be optional).

Also, onpong seems extraneous. The keepalive failure case should generate an onerror/onclose that indicates a keepalive timeout, IMO.
Comment 5 Simon Pieters 2011-09-12 19:47:43 UTC
*** Bug 14115 has been marked as a duplicate of this bug. ***
Comment 6 Iñaki Baz Castillo 2011-09-12 20:57:26 UTC
(In reply to comment #4)
> Also, onpong seems extraneous. The keepalive failure case should generate an
> onerror/onclose that indicates a keepalive timeout, IMO.

Be careful with that. Imagine the WS client sends a WS Ping in the same moment the WS server is sending a very text frame to the client (let's say 10 MB). Due to the WS protocol design, the server cannot send a new frame (neither a Pong frame !!!) until the current frame is totally sent to the client.

So the client could receive the Pong frame long time after it sent the Ping frame. If it raises an onerror/onclose event, it would cause problems.

Basically the Ping/Pong mechanism defined in WebSocket protocol is "a toy" and it's better not to rely on Pong timeouts.
Comment 7 Joel Martin 2011-09-12 21:26:52 UTC
If it's a keepalive mechanism, it shouldn't be timing out if it's receiving data. The ping/pong is to verify the connection while it is "idle".

Yet another reason why ping/pong this shouldn't be exposed in the API since the browser/UA may be aware that a large receive is in progress that it hasn't yet notified the Javascript (because the whole message hasn't been received yet).
Comment 8 Iñaki Baz Castillo 2011-09-12 21:28:29 UTC
(In reply to comment #7)
> Yet another reason why ping/pong this shouldn't be exposed in the API since the
> browser/UA may be aware that a large receive is in progress that it hasn't yet
> notified the Javascript (because the whole message hasn't been received yet).

I don't ask for an API function to send Ping frames, but just a WebSocket object parameter to set Ping interval from client to server. Just it.

And I agree with you. This is just as a keep-alive mechanism, no more.
Comment 9 Joel Martin 2011-09-12 21:34:22 UTC
Updated the summary to reflect keepalive (rather than ping/onpong).
Comment 10 Ian 'Hixie' Hickson 2011-09-14 18:04:03 UTC
I don't see why the scripts would have to have anything to do with this. The browser should just take care of this automatically.
Comment 11 Iñaki Baz Castillo 2011-09-14 18:28:47 UTC
(In reply to comment #10)
> I don't see why the scripts would have to have anything to do with this. The
> browser should just take care of this automatically.

Ian, how could the browser know whether the WebSocket server is supposed to mantain the connection by sending frames from server to client or not?

Why couldn't the script author instruct the web-browser to send periodic Ping frames to the server? I'm just talking about setting WebSocket object parameter:

    var myWebSocket = new WebSocket("ws://some-domain.com");
    myWebSocket.set_monitor_interval(120);

Why is this so hard?
Comment 12 Joel Martin 2011-09-14 19:26:12 UTC
Ian, are you saying that browsers SHOULD take care of this or rather that scripts should not?

If it's the former (browsers should implement), then that's probably worth mentioning in the API spec as an implementation expectation.

If it's the later (optional but implemented entirely if the browser if it present), that seems to mean that scripts need to implement their own keepalive/timeout mechanism if they care about it. That seems pessimal since the scripts don't have enough information to correctly implement it (and as mentioned large messages may cause unintended script side timeouts).
Comment 13 Joel Martin 2011-09-14 19:28:09 UTC
Sorry, that wasn't very clear. Try again: if keepalive is optional in the browser, then the only way to for scripts to know if the connection is alive is to send and receive something with a timeout. And doing this from the script side of things seems pessimal for several reasons.
Comment 14 Iñaki Baz Castillo 2011-09-14 21:29:37 UTC
(In reply to comment #13)
> Sorry, that wasn't very clear. Try again: if keepalive is optional in the
> browser, then the only way to for scripts to know if the connection is alive is
> to send and receive something with a timeout. And doing this from the script
> side of things seems pessimal for several reasons.

Hi Joel, just a comment. IMHO the only requirement from client side is to send "something" through the WebSocket connection periodically. There is no need to expect a response for it. Let me explain:

As I described in a previous comment, sometimes the Internet access is "down" (for example when the ADSL is temporarily lost). In that case, the client's TCP stack would not realize of it until it tries to send data over the connection. But in the moment it attempts to send data it would realize that the connection is down, so also the WebSocket client within the browser. Then the onclose() API callback would be called and the client application (JavaScript code) would realize of it and can react according (by trying to re-establish the connection or by warning the user). So there is no need of sending and receiving data.

If we now refer to "what" to send, then it's much easier to instruct the web-browser to periodically send WS Ping frames, rather than send WS messages at JavaScript level.

As you said in your last comment, this should be a requirement of the WebSocket API (which could mandate WS Ping frames from client to server) or could be activated by the JS script by setting some parameter in the WebSocket object as I've proposed in other comments.

Regards.

PS: Ian please, reopen this issue. IMHO there are arguments enough to keep discussing about this.
Comment 15 Iñaki Baz Castillo 2011-09-18 15:49:31 UTC
IMHO this report needs to be disussed since there is good rationale for it. Please let it open and let's discuss about it. Thanks.
Comment 16 Brian Raymor [MSFT] 2011-09-22 22:34:49 UTC
(In reply to comment #14)
> 
> IMHO the only requirement from client side is to send
> "something" through the WebSocket connection periodically. There is no need to
> expect a response for it. 

If this is the only requirement, then this could be implemented with an unsolicited pong; however, this would not address the case where the client is not receiving data because the server is hung (for example) and a response and/or timeout would be preferred.

There were a number of design discussions related to keep alive and/or heart beat on the IETF HyBi alias that were determined to be out-of-scope for this iteration of the protocol:

http://www.ietf.org/mail-archive/web/hybi/current/msg06646.html
http://www.ietf.org/mail-archive/web/hybi/current/msg06772.html

Theres also a related (but expired) draft on negotiating timeouts that was shared on HyBi:

http://tools.ietf.org/html/draft-thomson-hybi-http-timeout-00

It seems likely that keepalives must be addressed as an extension or in a future version of the protocol. Id prefer to not prematurely expose an API surface in V1 that would make it harder to adopt better solutions in the future based on actual deployment experience.  

I agree with Ian that the browser should automatically manage this on behalf of the application for V1. My recommendation is to resolve this bug as LATER.
Comment 17 Iñaki Baz Castillo 2011-09-22 22:50:45 UTC
(In reply to comment #16)
> If this is the only requirement, then this could be implemented with an
> unsolicited pong; however, this would not address the case where the client is
> not receiving data because the server is hung (for example) and a response
> and/or timeout would be preferred.

What you mean is "heartbeat" rather than "keepalive". By sending periodical keepalives (WS Ping) from client to server, the server would realize when the connection is dead (without having been a proper TCP disconnection).




> It seems likely that keepalives must be addressed as an extension or in a
> future version of the protocol.

I agree, since current draft does not define intervals at all for the arrival of a Pong (in fact, if the Ping is sent while the server is sending a very big WS message, the pong would arrive much later).


> Id prefer to not prematurely expose an API
> surface in V1 that would make it harder to adopt better solutions in the future
> based on actual deployment experience.  

I don't think that sending a periodical WS Ping from client to server could make harder the adoption of a future extension for keepalive/heartbeat. Clients implementing such new extension would indicate it somehow and, obviously, they wouldn't send "normal" WS ping frames as the current spec defines.



 
> I agree with Ian that the browser should automatically manage this on behalf of the application for V1.

I think that backawards compatibility (so no need to change user JS code) could be achieved by keeping the same WS API. For example, now it could be added the feature I ask for:

  websocket = new WebSocket("ws://domain.org");
  websocket.set_keepalive_interval(30);

and in case a future keepalive/heartbeat extension is defined, a new WS API function could be added:

  websocket.set_keepalive_expiration(4)

(which would mean that the client would detect a server problem if it does not receive a response to the sent Ping/Keepalive/HeartBeat request previously sent. 

What I mean is that current WS clients would send WS Ping frames at the interval defined by the user in websocket.set_keepalive_interval(N). In a future, if the browser implements some new keepalive/extension mechanism defined in WS 2.0, the function websocket.set_keepalive_interval(N) would send something different (rather than a WS Ping frame).


> My recommendation is to resolve this bug as LATER.

Well, given my arguments in this comment I cannot agree :)
Comment 18 Iñaki Baz Castillo 2011-09-22 22:51:41 UTC
(In reply to comment #17)
> What you mean is "heartbeat" rather than "keepalive". By sending periodical
> keepalives (WS Ping) from client to server, the server would realize when the
> connection is dead

Sorry, I meant "the ***client*** would realize when the connection is dead"
Comment 19 Ian 'Hixie' Hickson 2011-10-18 20:10:28 UTC
Could you elaborate on exactly what the use case is here?

Is the use case just to make sure that if the connection is killed without the server or client finding out, the client discovers it within a set time even if the script doesn't send anything?

Is the user case just to make sure that if the connection is killed without the server or client finding out, the _server_ discovers it within a set time even if the script doesn't send anything?

Is the use case to keep the connection "hot" so that NAT routers don't think the connection has been abandoned?

When would you _not_ want to send regular pings?

Why would you want to send regular pings at an interval different than another?
Comment 20 Iñaki Baz Castillo 2011-10-19 12:46:26 UTC
(In reply to comment #19)
> Is the use case just to make sure that if the connection is killed without the
> server or client finding out, the client discovers it within a set time even if
> the script doesn't send anything?

Yes. By sending periodical Pings in background the JS code can detect when the connection has been dropped abruptly (without TCP notification). For example when the ADSL becomes down.


> Is the user case just to make sure that if the connection is killed without the
> server or client finding out, the _server_ discovers it within a set time even
> if the script doesn't send anything?

Server are governed by admins which can implement WebSocket in the way they prefer, so they can send PING and react according. I didn't talk about server side.
>

> Is the use case to keep the connection "hot" so that NAT routers don't think
> the connection has been abandoned?

That's the motivation of any keep-alive mechanism for natter clients :)

 
> When would you _not_ want to send regular pings?

And that's the problem. Current WS API does not allow the JS to invoke WS Ping sending, neither the browser configuration allows sending WS Ping frames over an existing WS connection.

Simple suggestion: Browsers should send periodical WS Ping frames on every open WS connection. Teh interval could be determined by a default value (configurable in the browser about:config).


> Why would you want to send regular pings at an interval different than another?

An advance user (or a company network administrator) could set the required value based on its NAT nature. Just an option. In fact I prefer this to be implemented in the browser itself rather than being a JS API.
Comment 21 Brian Raymor [MSFT] 2011-10-20 02:40:52 UTC
(In reply to comment #20)
> 
> An advance user (or a company network administrator) could set the required
> value based on its NAT nature. Just an option. In fact I prefer this to be
> implemented in the browser itself rather than being a JS API.


We also prefer that keepalive be implemented in the browser as a configurable option rather than being exposed as an API. An API is not useful in many cases, because the developer will not have information about the network environment where the application is running.

IE10 implements a feature control key to set the keepalive interval. It looks like Mozilla implements similar configuration options?

* network.websocket.timeout.ping.request
* network.websocket.timeout.ping.response

Perhaps Jonas could confirm.
Comment 22 Ian 'Hixie' Hickson 2011-10-20 05:59:33 UTC
If we can just let the browser deal with it with no API change, that certainly seems ideal to me. Is everyone ok with that?
Comment 23 Iñaki Baz Castillo 2011-10-20 10:34:30 UTC
(In reply to comment #22)
> If we can just let the browser deal with it with no API change, that certainly
> seems ideal to me. Is everyone ok with that?

It's ok.

Take into account that current WS Ping/Pong is just valid as a keep-alive but not as a heart-beat mechanism (see comment above in which is explained that a WS Pong could be received much later due to an existing long WS message being already carried from).

So yes, making the browsers to send periodical WS Ping framse *by default* is useful IMHO. Maybe the interval could be configured (advanced configuration) within the browser configuration.

Regards.
Comment 24 Brian Raymor [MSFT] 2011-10-20 17:49:40 UTC
(In reply to comment #22)
> If we can just let the browser deal with it with no API change, that certainly
> seems ideal to me. Is everyone ok with that?

That sounds fine. Browser implementations should also be able to decide whether to use ping-pong or unsolicited pong.
Comment 25 Ian 'Hixie' Hickson 2011-10-20 19:59:42 UTC
Ok. I'll add a comment to the API spec to this effect, but will leave the normative aspects of this to the protocol spec.
Comment 26 Ian 'Hixie' Hickson 2011-10-25 04:38:18 UTC
Done.
Comment 27 contributor 2011-10-25 04:39:10 UTC
Checked in as WHATWG revision r6752.
Check-in comment: Add commentary on PING and PONG frames.
http://html5.org/tools/web-apps-tracker?from=6751&to=6752