UNPKG

@sex-pomelo/sex-pomelo

Version:

[![NPM version][npm-image-pomelo]][npm-url-pomelo] [![NPM version][npm-image-down]][npm-url-pomelo]

77 lines (63 loc) 1.99 kB
"use strict"; const Package = require('@sex-pomelo/sex-pomelo-protocol').Package; const reFilename = __filename.substring(__filename.indexOf("node_modules")) const logger = require('@sex-pomelo/sex-pomelo-logger').getLogger('pomelo', reFilename); /** * Process heartbeat request. * * @param {Object} opts option request * opts.heartbeat heartbeat interval */ let Command = function(opts) { opts = opts || {}; this.heartbeat = null; this.timeout = null; this.disconnectOnTimeout = opts.disconnectOnTimeout; if(opts.heartbeat) { this.heartbeat = opts.heartbeat * 1000; // heartbeat interval this.timeout = opts.timeout * 1000 || this.heartbeat * 2; // max heartbeat message timeout this.disconnectOnTimeout = true; } this.timeouts = {}; this.clients = {}; }; module.exports = Command; Command.prototype.handle = function(socket) { if(!this.heartbeat) { // no heartbeat setting return; } let self = this; if(!this.clients[socket.id]) { // clear timers when socket disconnect or error this.clients[socket.id] = 1; socket.once('disconnect', clearTimers.bind(null, this, socket.id)); socket.once('error', clearTimers.bind(null, this, socket.id)); } // clear timeout timer if(self.disconnectOnTimeout) { this.clear(socket.id); } socket.sendRaw(Package.encode(Package.TYPE_HEARTBEAT)); if(self.disconnectOnTimeout) { self.timeouts[socket.id] = setTimeout(function() { logger.info('client %j heartbeat timeout.', socket.id); socket.disconnect(); }, self.timeout); } }; Command.prototype.clear = function(id) { let tid = this.timeouts[id]; if(tid) { clearTimeout(tid); delete this.timeouts[id]; } }; let clearTimers = function(self, id) { delete self.clients[id]; let tid = self.timeouts[id]; if(tid) { clearTimeout(tid); delete self.timeouts[id]; } };