UNPKG

2.77 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3const Debug = require("debug");
4const events = require("events");
5const util = require("util");
6const WebSocket = require("ws");
7const debug = Debug('ionic:discover:comm');
8const PREFIX = 'ION_CS';
9class 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}
82exports.CommServer = CommServer;
83function isPayload(payload) {
84 return payload && typeof payload.event === 'string';
85}