I'm no expert on this topic but I interpreted close timeout as being the amount of time after a disconnect, that the client has to reconnect and still get the same connection to resume. After that time, the connection is assumed to be dead and may be garbage collected.
So it may be the case there's some confounding events going on in that the close timeout is not causing your disconnects; rather the connection is dying immediately but it's only reported after close timeout expires because that's how long it waits around for the client to reconnect before giving up. This would explain why it's always 25 seconds or whatever your close timeout value is before you get the disconnect.
Here's what I see in a normally operating connection:
debug - client authorized
info - handshake authorized 6532049221552199402
debug - set heartbeat interval for client 6532049221552199402
debug - client authorized for
debug - websocket writing 1::
Got packet from 6532049221552199402 <-- Here the server receives a packet from my client (I'm logging this, not socketio)
debug - sending data ack packet
debug - websocket writing 6:::1+[{ //What my server responds with }]
info - transport end <-- My client now navigates away which tells the sever to close
debug - set close timeout for client 6532049221552199402
debug - cleared close timeout for client 6532049221552199402
debug - cleared heartbeat interval for client 6532049221552199402
debug - discarding transport
The "undefined" being printed in your log is troubling, and it seems that the "cleared hearbeat interval..." log is missing so maybe something is wrong with your heartbeat interval?
You might have already done this but the example socketio app works and would be a good base test to make sure everything is set up correctly without having to worry about the code.
Best,
Jason Chen