UNPKG

@ionic/discover

Version:

Simple UDP based protocol for service discovery implemented in pure JS.

88 lines (87 loc) 2.92 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.CommServer = void 0; const tslib_1 = require("tslib"); const debug_1 = require("debug"); const events = tslib_1.__importStar(require("events")); const util = tslib_1.__importStar(require("util")); const ws_1 = tslib_1.__importDefault(require("ws")); const debug = (0, debug_1.debug)('ionic:discover:comm'); const PREFIX = 'ION_CS'; class CommServer extends events.EventEmitter { constructor(namespace, /** * Unique identifier of the publisher. */ id, /** * Port of communication server. */ port) { super(); this.namespace = namespace; this.id = id; this.port = port; } get clients() { return this.server ? this.server.clients : new Set(); } start() { if (this.server) { throw new Error('server already initialized'); } const server = this.server = new ws_1.default.Server({ clientTracking: true, host: '0.0.0.0', port: this.port }); return new Promise((resolve, reject) => { server.on('error', err => { this.emit('error', err); }); server.on('connection', ws => { debug(`Connection established. ${server.clients.size} clients.`); ws.on('message', data => { debug(`Received %O`, data.toString()); const message = this.parseData(data); if (message) { this.emit(message.event, message); } }); ws.on('close', () => { debug(`Connection closed. ${server.clients.size} clients.`); }); }); server.on('listening', () => { debug('Comm server listening: %O', { host: server.options.host, port: this.port }); resolve(); }); }); } parseData(data) { try { const msg = data.toString(); const msgprefix = msg.substring(0, PREFIX.length); if (msgprefix !== PREFIX) { throw new Error(`Invalid prefix for message: ${msgprefix}`); } const payload = JSON.parse(msg.substring(PREFIX.length)); if (!isPayload(payload)) { throw new Error(`Invalid payload: ${util.inspect(payload)}`); } return payload; } catch (e) { debug(e); } } stop() { if (!this.server) { throw new Error('server not initialized'); } const server = this.server; return new Promise(resolve => { server.close(() => resolve()); }); } } exports.CommServer = CommServer; function isPayload(payload) { return payload && typeof payload.event === 'string'; }