1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | exports.CommServer = void 0;
|
4 | const Debug = require("debug");
|
5 | const events = require("events");
|
6 | const util = require("util");
|
7 | const WebSocket = require("ws");
|
8 | const debug = Debug('ionic:discover:comm');
|
9 | const PREFIX = 'ION_CS';
|
10 | class CommServer extends events.EventEmitter {
|
11 | constructor(namespace,
|
12 | /**
|
13 | * Unique identifier of the publisher.
|
14 | */
|
15 | id,
|
16 | /**
|
17 | * Port of communication server.
|
18 | */
|
19 | port) {
|
20 | super();
|
21 | this.namespace = namespace;
|
22 | this.id = id;
|
23 | this.port = port;
|
24 | }
|
25 | get clients() {
|
26 | return this.server ? this.server.clients : new Set();
|
27 | }
|
28 | start() {
|
29 | if (this.server) {
|
30 | throw new Error('server already initialized');
|
31 | }
|
32 | const server = this.server = new WebSocket.Server({ clientTracking: true, host: '0.0.0.0', port: this.port });
|
33 | return new Promise((resolve, reject) => {
|
34 | server.on('error', err => {
|
35 | this.emit('error', err);
|
36 | });
|
37 | server.on('connection', ws => {
|
38 | debug(`Connection established. ${server.clients.size} clients.`);
|
39 | ws.on('message', data => {
|
40 | debug(`Received %O`, data.toString());
|
41 | const message = this.parseData(data);
|
42 | if (message) {
|
43 | this.emit(message.event, message);
|
44 | }
|
45 | });
|
46 | ws.on('close', () => {
|
47 | debug(`Connection closed. ${server.clients.size} clients.`);
|
48 | });
|
49 | });
|
50 | server.on('listening', () => {
|
51 | debug('Comm server listening: %O', { host: server.options.host, port: this.port });
|
52 | resolve();
|
53 | });
|
54 | });
|
55 | }
|
56 | parseData(data) {
|
57 | try {
|
58 | const msg = data.toString();
|
59 | const msgprefix = msg.substring(0, PREFIX.length);
|
60 | if (msgprefix !== PREFIX) {
|
61 | throw new Error(`Invalid prefix for message: ${msgprefix}`);
|
62 | }
|
63 | const payload = JSON.parse(msg.substring(PREFIX.length));
|
64 | if (!isPayload(payload)) {
|
65 | throw new Error(`Invalid payload: ${util.inspect(payload)}`);
|
66 | }
|
67 | return payload;
|
68 | }
|
69 | catch (e) {
|
70 | debug(e);
|
71 | }
|
72 | }
|
73 | stop() {
|
74 | if (!this.server) {
|
75 | throw new Error('server not initialized');
|
76 | }
|
77 | const server = this.server;
|
78 | return new Promise(resolve => {
|
79 | server.close(() => resolve());
|
80 | });
|
81 | }
|
82 | }
|
83 | exports.CommServer = CommServer;
|
84 | function isPayload(payload) {
|
85 | return payload && typeof payload.event === 'string';
|
86 | }
|