From: Darren Date: Tue, 23 Sep 2014 21:11:47 +0000 (+0100) Subject: App level heartbeat to ensure clients get disposed() when they disappear X-Git-Url: https://vcs.fsf.org/?a=commitdiff_plain;h=4d1c21194c39d06ebfad9cc69b6035dd47537266;p=KiwiIRC.git App level heartbeat to ensure clients get disposed() when they disappear --- diff --git a/client/src/models/gateway.js b/client/src/models/gateway.js index 7fe7cf3..4fe707d 100644 --- a/client/src/models/gateway.js +++ b/client/src/models/gateway.js @@ -76,6 +76,16 @@ _kiwi.model.Gateway = Backbone.Model.extend({ // Reset the disconnect_requested flag that.disconnect_requested = false; + // Each minute we need to trigger a heartbeat. Server expects 2min, but to be safe we do it every 1min + var heartbeat = function() { + if (!that.rpc) return; + + that.rpc('kiwi.heartbeat'); + that._heartbeat_tmr = setTimeout(heartbeat, 60000); + }; + + heartbeat(); + console.log("_kiwi.gateway.socket.on('open')"); }); diff --git a/server/client.js b/server/client.js index 724b51c..609c906 100755 --- a/server/client.js +++ b/server/client.js @@ -52,6 +52,11 @@ var Client = function (websocket, opts) { // Handles the kiwi.* RPC functions this.attachKiwiCommands(); + websocket.on('message', function() { + // A message from the client is a sure sign the client is still alive, so consider it a heartbeat + that.heartbeat(); + }); + websocket.on('close', function () { websocketDisconnect.apply(that, arguments); }); @@ -87,14 +92,40 @@ Client.prototype.sendKiwiCommand = function (command, data, callback) { Client.prototype.dispose = function () { Stats.incr('client.disposed'); - this.disposed = true; + if (this._heartbeat_tmr) { + clearTimeout(this._heartbeat_tmr); + } + this.rpc.dispose(); + this.websocket.removeAllListeners(); + + this.disposed = true; this.emit('dispose'); + this.removeAllListeners(); }; +Client.prototype.heartbeat = function() { + if (this._heartbeat_tmr) { + clearTimeout(this._heartbeat_tmr); + } + + // After 2 minutes of this heartbeat not being called again, assume the client has disconnected + console.log('resetting heartbeat'); + this._heartbeat_tmr = setTimeout(_.bind(this._heartbeat_timeout, this), 120000); +}; + + +Client.prototype._heartbeat_timeout = function() { + console.log('heartbeat stopped'); + Stats.incr('client.timeout'); + this.dispose(); +}; + + + Client.prototype.attachKiwiCommands = function() { var that = this; @@ -130,6 +161,12 @@ Client.prototype.attachKiwiCommands = function() { build_version: args.build_version.toString() || undefined }; }); + + + // Just to let us know the client is still there + this.rpc.on('kiwi.heartbeat', function(callback, args) { + that.heartbeat(); + }); };