const sleep = require('../libs/util.js').sleep; const EventEmitter = require('events'); const Message = require('./Message.js'); class Heartbeat extends EventEmitter { constructor(client) { super(); this.interval = config?.server?.heartbeat || 10000; this.client = client; this.#listenForPingPong(); this.#sendPing(); } async #sendPing() { if (this.destroyed === true) { return; } if (this.timeout !== undefined) { clearTimeout(this.timeout); } if (this.alive === false) { this.emit('timeout'); } if (this.alive === undefined) { await sleep(this.interval); } this.alive = false; this.ping = Date.now(); await new Message('ping').send(this.client); await sleep(this.interval); this.#sendPing(); } async #listenForPingPong() { eventparser.on('ping', () => { logger.debug(this.client.getTag() + ' handling event \'ping\', responding with \'pong\'...'); new Message('pong').send(this.client); }); eventparser.on('pong', () => { logger.debug(this.client.getTag() + ' handling event \'pong\'...'); this.alive = true; this.pong = Date.now(); this.latency = this.pong - this.ping; this.emit('network-statistics', { ping: this.ping, pong: this.pong, latency: this.latency }); }); } destroy() { this.destroyed = true; eventparser.removeAllListeners('ping'); eventparser.removeAllListeners('pong'); } } module.exports = Heartbeat;