Heartbeats & detecting dead connections (sockjs-node/client)

1,390 views
Skip to first unread message

arju...@gmail.com

unread,
Dec 22, 2013, 2:47:37 PM12/22/13
to soc...@googlegroups.com
Hi there! I am new here, though I've been using sockjs for some time now, in project experiments.

This is in reference to a potentially serious connection idling issue I've encountered, and it looks like it's been encountered a few times before by some people (perhaps the same person)
https://github.com/sockjs/sockjs-node/issues/129
https://github.com/sockjs/sockjs-node/issues/127

Even with just a few connections (2 or 3), I can reproduce.

When testing, if these connections idle for a while, or if I close the lid of my laptop, the close event for these connections is not emitted and the connections "stay open". These connections will stay open indefinitely... and be totally dissociated from a real client on the other side. They are never cleaned up even though the disconnect_delay is set to something like 5 seconds, as well as the "heartbeat_delay" is set for 25 seconds. If I leave my laptop closed for a number of hours and open it again, the connections are unresponsive, yet no close event is logged/triggered.

This may be related to the Chrome issue: https://code.google.com/p/chromium/issues/detail?id=76358 which doesn't seem to be wanting to be resolved any time soon.

In any case, the expected behaviour would be that if the heartbeat is not heard for a while, the connection would close, much like what is expected with disconnect_delay.

Some questions:
Is the sockjs native heartbeat being done on both the client and the server side?
If it is using a setInterval function for every connection, this could eat up memory to have a setInterval counter for each connection, as well as use extra CPU time, yeah, though I think these functions are stored in the prototype for the Session?
Most importantly: Is there any way to override/toggle off the default heartbeat functionality to save resources and build my own?

----

As a slightly side note, here is an algorithm I'd want to implement for a (potentially) more reliable heartbeat on the server side:
Client side:
send to server a frame designated to indicate a heartbeat message (sock-js is currently using 'h'?).

On server:

if(message === 'h')
  onHeartBeat(this);

function onHeartBeat(connection){
  connection.lastHeartBeatTimeStamp = new Date().getTime();
}

setInterval(
  var currentTime = new Date().getTime();
  for(var connection in connectionMap){
    if(connection.lastHeartBeatTimeStamp+heartBeatDelay < currentTime)
      connection.close(); //to emit the event that is relied on.
      //do other things to ensure the connection is removed
  }
, heartBeatDelay);

I suppose I can still implement this, but it would be on top of the existing heartbeat functionality, and it would be redundant.

Your thoughts greatly appreciated!

Thanks!
Arjun

Eric Mill

unread,
Dec 22, 2013, 11:20:31 PM12/22/13
to arju...@gmail.com, SockJS
I actually wasn't aware sockjs had its own native heartbeating functionality, but it wasn't working for me this time last year -- I ended up rolling my own, which is in operation at https://isitchristmas.com/ right now. There's a client-side and server-side heartbeat, in case either side sees the other one drop out.

I didn't have to disable sockjs' own heartbeating or anything - I just used a setInterval on either side that needs to be canceled by an incoming pulse from the other side.


(ctrl+F for 'heartbeat')

(Server-side code is actually not the most current code right now, but the heartbeat logic is unchanged from last year.)

-- Eric


--
You received this message because you are subscribed to the Google Groups "sockjs" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sockjs+un...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.



--
Reply all
Reply to author
Forward
0 new messages