Subject: [hybi] Are keep-alives necessary? Was: Re: NAT reset recovery? Was: Extensibility mechanisms?

From: Hugh Winkler <[email-masked]>
Date: Tue, 20 Apr 2010 11:17:26 -0500

On Mon, Apr 19, 2010 at 4:36 PM, Vladimir Katardjiev <[email-masked]> wrote:

>
> Having said that, from a mobile perspective this is disastrous. In the worst-case scenario, if your keepalive interval is 5 minutes, you could end up sending a keepalive message every 2.5 minutes. This would wake up the radio twice as often, and, consequently, halve battery life. In a scenario where the server's keepalive is triggered by the client's, the message from the server would likely arrive within the timeframe that the radio is "awake" anyway (3-5 seconds on smartphones) and thus avoid waking it up again.
>

I'm unsure keep-alives are driven by requirements.

It's only necessary to keep the connection alive across long periods
of no activity if you require that applications can expect their
connections to be stateful.

One requirement of web sockets protocol is that it must support WSAPI.
So if WSAPI were to explicitly say that applications may not expect
the remote end of a connection to maintain state across send()s, then
a client implementation of WSP could just initiate a new TCP
connection, if it discovers upon sending that the underlying
connection has been closed.

WSAPI as written doesn't explicitly say whether applications can
expect the server to maintain state, and I think reasonable people can
assume that's implied by the semantics of "connection". But if the
WSAPI explicitly were to say that send() is idempotent, then WSP
wouldn't need to keep the TCP connection alive. An implementation
could open a new TCP connection under the hood for any send. And
handset manufacturers would thank you.

Hugh

---

From: Vladimir Katardjiev <[email-masked]>
Date: Tue, 20 Apr 2010 18:39:47 +0200

> handset manufacturers would thank you.

All technically correct, and completely accurate if we assume the only reason the WebSocket API would be used would be to send() data to a remote endpoint. But websocket is a bidirectional API, meaning it should both send and receive messages. Going back to the tic tac toe example, my side (client) is waiting for the other side (server) to make their turn, there will never come a point in time at which my side should send a message (it's not my turn). There's also no reasonable expectation of when the other side is going to make their move (=send me a message). And even if the remote side discovers the connection is dropped, it can't do anything because I'm behind a NAT.

So either the WS realisation would need to open a new TCP connection every 5 minutes of no traffic (just in case the old one died, because there's no way to recognise that), or it would need some form of message that would trigger traffic on the channel thus making it clear it's still open. Otherwise the WSAPI won't be able to receive messages from the remote endpoint at arbitrary time points.

Now, if I let every single amateur programmer do whatever they read on the internet, they'll just setTimeout("ping()", 30000) just to be on the safe side and the handset manufacturers would be after my throat.

Of course, if the semantics for send() in the web socket API didn't require the remote host being able to arbitrarily send one or more messages without client action, then, yes, the TCP transport could be broken at will with no ill effects, and you don't need to keep it alive. But I think XmlHttpRequest.send() fills that functionality already. 

Vladimir

---

From: Hugh Winkler <[email-masked]>
Date: Tue, 20 Apr 2010 16:04:32 -0500

> So either the WS realisation would need to open a new TCP connection every 5 minutes of no traffic (just in case the old one died, because there's no way to recognise that), or it would need some f…

Yes, duh. I don't know what I was thinking. That's the most important
case: replacing hanging GET. Of course it's necessary to keep that TCP
connection alive so I can receive the message from the server, my
mistake.

Hugh

---

From: Jamie Lokier <[email-masked]>
Date: Tue, 20 Apr 2010 22:27:55 +0100

Hugh Winkler wrote:
> > Having said that, from a mobile perspective this is disastrous. In
> > the worst-case scenario, if your keepalive interval is 5 minutes,
> > you could end up sending a keepalive message every 2.5
> > minutes. This would wake up the radio twice as often, and,
> > consequently, halve battery life. In a scenario where the server's
> > keepalive is triggered by the client's, the message from the
> > server would likely arrive within the timeframe that the radio is
> > "awake" anyway (3-5 seconds on smartphones) and thus avoid waking
> > it up again.
> 
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> connection has been closed.
  ^^^^^^^^^^^^^^^^^^^^^^^^^^

It takes TCP a very long time to discover that the connection has gone
away after sending - depending on how it went away.

We're talking between 15 minutes and 2 hours, depending on platform.
(Max TCP retransmits, if platform doesn't use TCP-level keepalives.)

Nobody wants a web page showing their live inbox that is 2 hours out
of date because it didn't know to make a new connection.

> handset manufacturers would thank you.

Letting send() messages be duplicated by the WS implementation (which
is what idempotent means here) is not reasonable.  Application writers
would routinely ignore that part of the spec because it doesn't happen
most of the time and it's hard to work with.  It *could* be hidden
from applications with unique message ids and a history buffer on the
server, however.

Disconnecting when idle breaks things like "online presence" and
"client receives event when something happens on server".

Those are big reasons for using WebSocket.

Handset manufacturers would not be happy, because your proposal would
force those kind of apps to send a request every few seconds, like
they do today over HTTP and we're trying to improve on.  (Think of
Facebook etc. using up your phone's battery despite no updates.)
(Multiply by 20 other background apps.)

-- Jamie

---

From: Bill de hOra <[email-masked]>
Date: Fri, 23 Apr 2010 00:16:31 +0100

> Having said that, from a mobile perspective this is disastrous. 
 > In the worst-case scenario, if your keepalive interval is 5 minutes,
 > you could end up sending a keepalive message every 2.5 minutes.
> This would wake up the radio twice as often, and, consequently, 
> halve battery life. 

This depends on the network, eg if a keepalive shifts you up to CELL_DCH 
then you will burn more battery than if you were shifted to CELL_FACH. 
Battery life is very much a function of the network.

Bill