[hunchentoot-devel] Socket timeout issues

Toby tobia.conforto at linux.it
Thu Nov 16 22:34:17 UTC 2006


Hi all

I'm having some trouble with connection timeouts.

I'm writing an AJAX application where I need to push values from the
server to the client at random times (it's a chat application.) 

To avoid polling the server every second, I wrote it like this, to
exploit hanging connections:
 - the client opens a connection with XMLHttpRequest 
 - the server doesn't respond (the handler waits on a condition variable),
   keeping the connection hanging
 - when the server has data to send (new lines of chat) it does so, and:
    - the client receives the data, closes the connection and starts over
 - if the connection timeouts (on either end), the client starts over

This method worked beautifully on SBCL + TBNL + mod_lisp2 + Apache2, on
any browser.  It gave me the lowest possible lag (equal to the network
latency) with very little network overhead.

Now on SBCL 0.9.17 + Hunchentoot 0.4.9 I'm having trouble with the Opera
browser (and possibly others: I've only tested it on Opera and Firefox.)

By the way, Firefox doesn't seem to have any connection timeout: I've
seen it receive a response after a (sleep 1800), without any packet sent
by either side in half an hour!

Anyway I've used a sniffer to understand what's going on.  Usually, when
the connection times out client-side, these packets are exchanged:

  C -> S  ACK FIN
( C <- S  ACK     )
  C <- S  ACK FIN
  C -> S  ACK

This way both sides agree that the connection is over.

But on SBCL + Hunchentoot vs. Opera, after 2 minutes the client times out
and I see the following exchange:

  C -> S  ACK FIN
  C <- S  ACK

I can't make sense of it: why does the server acknowledge the FIN packet
but fail to send its own?

As a result the client thinks it's almost over... enough not to accept
any data from the same connection again, but not enough to stop spinning
and fire the XMLHttpRequest callback (which would open a new connection.)

Even worse, the server thinks it's still open, so it will send any new
data on that wire.  But the data won't be accepted by the client, which
will send a RST as soon as it sees stuff coming from a 'dead' connection.


Help!


Toby

PS: All these tests were done with :read-timeout nil
Maybe I should set it to 119 and forget about it :-)



More information about the Tbnl-devel mailing list