heartbeat.js 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. var Package = require('pomelo-protocol').Package;
  2. var logger = require('pomelo-logger').getLogger('pomelo', __filename);
  3. /**
  4. * Process heartbeat request.
  5. *
  6. * @param {Object} opts option request
  7. * opts.heartbeat heartbeat interval
  8. */
  9. var Command = function(opts) {
  10. opts = opts || {};
  11. this.heartbeat = null;
  12. this.timeout = null;
  13. if(opts.heartbeat) {
  14. this.heartbeat = opts.heartbeat * 1000; // heartbeat interval
  15. this.timeout = opts.timeout * 1000 || this.heartbeat * 2; // max heartbeat message timeout
  16. }
  17. this.timeouts = {};
  18. this.clients = {};
  19. this.disconnectOnTimeout = opts.disconnectOnTimeout;
  20. };
  21. module.exports = Command;
  22. Command.prototype.handle = function(socket) {
  23. if(!this.heartbeat) {
  24. // no heartbeat setting
  25. return;
  26. }
  27. var self = this;
  28. if(!this.clients[socket.id]) {
  29. // clear timers when socket disconnect or error
  30. this.clients[socket.id] = 1;
  31. socket.once('disconnect', clearTimers.bind(null, this, socket.id));
  32. socket.once('error', clearTimers.bind(null, this, socket.id));
  33. }
  34. // clear timeout timer
  35. if(self.disconnectOnTimeout) {
  36. this.clear(socket.id);
  37. }
  38. socket.sendRaw(Package.encode(Package.TYPE_HEARTBEAT));
  39. if(self.disconnectOnTimeout) {
  40. self.timeouts[socket.id] = setTimeout(function() {
  41. logger.info('client %j heartbeat timeout.', socket.id);
  42. socket.disconnect();
  43. }, self.timeout);
  44. }
  45. };
  46. Command.prototype.clear = function(id) {
  47. var tid = this.timeouts[id];
  48. if(tid) {
  49. clearTimeout(tid);
  50. delete this.timeouts[id];
  51. }
  52. };
  53. var clearTimers = function(self, id) {
  54. delete self.clients[id];
  55. var tid = self.timeouts[id];
  56. if(tid) {
  57. clearTimeout(tid);
  58. delete self.timeouts[id];
  59. }
  60. };