UNPKG

pr-ws-monitor

Version:
106 lines (91 loc) 3.1 kB
"use strict"; const EventEmitter = require("events"); var defaults = { "ts": 1000, // 1-sec "error": 60000, // 1-min "audit": 15000 // 15-sec (4-times within error-interval) }; function getOptions(options) { var opts = options || {}; opts = Object.assign.apply(null, Object.keys(defaults).map(prop => ({ [prop]: opts[prop] }))); Object.keys(defaults).forEach(function each(o) { opts[o] = opts[o] || defaults[o]; }); return opts; } function getObjectData(self) { self._wsmon = self._wsmon || {}; return self._wsmon; } class WsMonitor extends EventEmitter { constructor(wss, options) { var data; super(); data = getObjectData(this); data.wss = wss; data.opts = getOptions(options); } start() { var data = getObjectData(this); // check client-tracking if (data.wss.options.clientTracking === false) { this.emit("error", "need to enable clientTracking in ws-server"); } // setup now time-stamp data.now = Date.now(); data.nowId = setInterval(function nowTs() { data.now = Date.now(); }, data.opts.ts); // setup time-stamp for existing connections data.wss.clients.forEach(function eachSock(sock) { sock._updateSockTs = function _updateSockTs() { sock._ats = data.now; }; sock._ats = data.now; sock.on("pong", sock._updateSockTs); sock.on("message", sock._updateSockTs); }); // setup time-stamp for new connections data.wss.on("connection", function sockConnection(sock) { sock._updateSockTs = function _updateSockTs() { sock._ats = data.now; }; sock._ats = data.now; sock.on("pong", sock._updateSockTs); sock.on("message", sock._updateSockTs); }); // setup auditing data.auditId = setInterval(function auditConnections() { data.wss.clients.forEach(function eachSock(sock) { var lag = Date.now() - sock._ats; if (lag > data.opts.error) { sock.removeListener("pong", sock._updateSockTs); sock.removeListener("message", sock._updateSockTs); sock.close(); } else if (lag > data.opts.audit) { sock.ping("WsMonitor PING", {}, false); } }); }, data.opts.audit); } stop() { var data = getObjectData(this); // clear now & audit if (data.nowId) { clearInterval(data.nowId); data.nowId = null; } if (data.auditId) { clearInterval(data.auditId); data.auditId = null; } data.wss.clients.forEach(function eachSock(sock) { sock.removeListener("pong", sock._updateSockTs); sock.removeListener("message", sock._updateSockTs); }); } } // export module.exports = WsMonitor;