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