olark/socket.io-client — pull request #1 by bdimcheff (2013-03-26 16:44:55+00:00)
Title: This fixes the reconnect loop that occurs after heartbeat timeout.

The bug is something like this:

1. Establish a socket.io connection.
2. Kill your internet connection for long enough for the heartbeat
timeout to fire.
3. Reconnect your internet. The socket will reconnect, but will soon be
disconnected by a heartbeat timeout from the PREVIOUS websocket
connection.

This is what happens internally:

- Heartbeat calls transport.onClose
- transport.onClose calls socket.onDisconnect and thus socket.reconnect
- socket.reconnect swaps out the old transport for a new one
- socket.onDisconnect also calls transport.close and thus
websocket.close
- websocket.close puts the websocket into the CLOSING state
- new transport/websocket successfully establishes a connection
- old websocket (after some time) goes from CLOSING to CLOSED and fires
its onclose handler which calls transport.onClose on the OLD transport
- old transport still has a reference to the current socket, so it calls
socket.onDisconnect, which closes the *new* socket
- loop back and do it all again

In order for this to happen, the reconnect has to take place *after* the
socket reconnects, but *before* the original socket times out and
switches to the CLOSED state.

Fix:

My fix is pretty terrible. I'm checking to make sure the socket's
transport is the same as the transport handling the onClose event.
Perhaps a better solution would be to remove the onclose handler on the
websocket if the connection is explicitly closed. There also may be
some better way of cleaning up the old transport during a reconnect.