[jdev] XMPP Ping/Keepalive: Recommended method ?
Bruce Campbell
list-jdev at vicious.dropbear.id.au
Tue Jun 27 05:09:23 CDT 2006
On Mon, 26 Jun 2006, Joe Hildebrand wrote:
> On Jun 19, 2006, at 1:15 AM, Sergei Golovan wrote:
>
>> The problem is that this "ping" is not a ping at all because it only
>> sends data and does not expect reply.
>
> Well, not really. You'll get a TCP ack back, which should be enough to keep
> the lights on.
Not if you are dealing with inspection-type firewalls which don't really
treat a TCP ACK as a data packet.
> Some servers can also be configured to send space
> keep-alives. If both sides use this algorithm things seem to work pretty
> well:
>
> 1) set a timer to some amount of time, say 30 seconds
> 2) when the timer fires, send a space
> 3) whenever you send something, reset to the timer to zero
> 4) whenever you receive something, reset the timer to zero
It works to a point (being probably 95% of cases). If you have a client
sending pings every 40 seconds unless first reset, and the server sending
pings every 30 seconds unless first reset, the client's first ping will be
the one that discovers that the packet-inspecting firewall wants to see
non-TCP-ack packets.
If you want to go down that path, you need two timeouts; a short one (30
seconds) to be reset each time a packet is sent or received as above, and
a longer one (60 seconds) to trigger a send locally. In practice, this
eventually settles down to each side sending a packet at 60 second
intervals, with a roughly 30 second gap between them.
Even so, this requires server-side configuration; the server may not do
whitespace pings for policy reasons.
> this allows you to detect dead links about as quickly as possible, without
> increasing network traffic any more than absolutely necessary.
There isn't a lot of difference between a TCP packet containing a single
whitespace character, and a TCP packet containing a dummy <iq/> or
<message/> stanza. Neither will be fragmented.
A whitespace ping is less expensive on the server side, as it gets thrown
out by the c2s-equivilant component, and just returns a TCP ack. Conversely,
a dummy stanza will always be more expensive, as depending on the server
design, it may be routed through several components to get to the
sm-equivilant, then routed back and sent to the client in a second
TCP-data + TCP-ack pair.
However, the gain is that the client 'knows' that the server is fully
functioning, and any firewalls in between which expect to see data flowing
in both directions have nicely had their idle timers reset, vs the client
just knowing that the TCP stream to the c2s component is still
functioning.
On the reverse issue, I don't think that servers should generate anything
more than whitespace pings to verify an ongoing TCP stream with a client.
This would require changes to most client (which are user-driven, not
server driven), and generally servers want to clean up after any departed
TCP streams as soon as possible.
I guess the point I'm trying to make is, do you want the clients to know
that their next <message/> will not generate a TCP error, or do you want
clients to know that their next <message/>, if not delivered, will come
back with an undeliverable stanza ?
--
Bruce Campbell
More information about the JDev
mailing list