[dev] Maintaining connection without keepalive support?


Hi, my question is not strictly streaming api related, thank to the mods to move this post if necessary.

I’m (french and) working on my own streaming api that is served by a nodejs server. It is very similar to twitter streaming api: response is sent as a very long file and whenever no event has to be sent empty lines are used to maintain connection alive.

My problem is I can’t detect whenever remote connections drop brutally. It uselly happens when network channel between clients and the server has gone down.

I could use tcp keepalive mecanism but I’ve read that this is not what twitter does (“connection” header is set to “close” on twitter streaming packets). It seems twitter is using data structures that keep track of packets that have been sent. Those data structures can tell whenever remote clients read data.

Since there is no ping/pong mecanism on streaming api’s application layer protocol, how is this working? Can i reproduce it with my nodejs server?

Thanks for reading and sorry for my poor english.


I think I found how twitter devs do.

In fact, the OS implement an algorithm in which it tries to send a tcp packet periodically during a certain amount of time.

On linux for example, you can check some metrics to find out how the kernel behaves when sending data does not receive ACK (/proc/sys/net/ipv4/tcp_retries1 and /proc/sys/net/ipv4/tcp_retries2).

On recent kernel versions, devs can specifies the maimum amount of time in ms that transmitted data may remain unacknowledged before TCP will forcefully close the corresponding connection and return ETIMEDOUT to the application (cf http://stackoverflow.com/questions/5907527/application-control-of-tcp-retransmission-on-linux). So, I created a patch for nodejs that let devs set this parameter.

My tests so far show exactly what I want: if a chunk of data does not receive ACK after 10s, the socket receives a close event. If people are interested I may try to explain better what I did. Meantime, I’ll try to send a pull-request to both libuv and nodejs projects.