1 | "use strict";
|
2 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
3 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
4 | return new (P || (P = Promise))(function (resolve, reject) {
|
5 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
6 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
7 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
8 | step((generator = generator.apply(thisArg, _arguments || [])).next());
|
9 | });
|
10 | };
|
11 | Object.defineProperty(exports, "__esModule", { value: true });
|
12 | const expect = require("@fantasticfiasco/expect");
|
13 | const events = require("events");
|
14 | const logging_1 = require("./logging");
|
15 | const network_interfaces_1 = require("./network-interfaces");
|
16 | const options_1 = require("./options");
|
17 | const root_descriptions_1 = require("./root-descriptions");
|
18 | const sockets_1 = require("./sockets");
|
19 |
|
20 |
|
21 |
|
22 | class Discovery {
|
23 | |
24 |
|
25 |
|
26 |
|
27 | constructor(options) {
|
28 | this.eventEmitter = new events.EventEmitter();
|
29 | this.options = options || {};
|
30 | }
|
31 | |
32 |
|
33 |
|
34 |
|
35 | start() {
|
36 | return __awaiter(this, void 0, void 0, function* () {
|
37 | expect.toNotExist(this.sockets, 'Discovery has already been started');
|
38 | logging_1.log('Discovery#start');
|
39 | yield this.setup();
|
40 | });
|
41 | }
|
42 | |
43 |
|
44 |
|
45 | stop() {
|
46 | return __awaiter(this, void 0, void 0, function* () {
|
47 | expect.toExist(this.sockets, 'Discovery has not been started');
|
48 | logging_1.log('Discovery#stop');
|
49 | yield this.teardown();
|
50 | });
|
51 | }
|
52 | |
53 |
|
54 |
|
55 | search() {
|
56 | return __awaiter(this, void 0, void 0, function* () {
|
57 | expect.toExist(this.sockets, 'Discovery has not been started');
|
58 | logging_1.log('Discovery#search');
|
59 | for (const socket of this.sockets) {
|
60 | if (socket instanceof sockets_1.MSearchSocket) {
|
61 | yield socket.search();
|
62 | }
|
63 | }
|
64 | });
|
65 | }
|
66 | |
67 |
|
68 |
|
69 |
|
70 | onHello(callback) {
|
71 | this.eventEmitter.on('hello', (device) => callback(device));
|
72 | }
|
73 | |
74 |
|
75 |
|
76 |
|
77 | onGoodbye(callback) {
|
78 | this.eventEmitter.on('goodbye', (device) => callback(device));
|
79 | }
|
80 | setup() {
|
81 | return __awaiter(this, void 0, void 0, function* () {
|
82 | this.sockets = [];
|
83 | const addresses = network_interfaces_1.getIPv4Addresses();
|
84 | logging_1.log('Discovery#setup - interface addresses: %o', addresses);
|
85 |
|
86 | yield this.setupSocket(new sockets_1.NotifySocket(addresses));
|
87 |
|
88 | for (const address of addresses) {
|
89 | yield this.setupSocket(new sockets_1.MSearchSocket(address));
|
90 | }
|
91 | });
|
92 | }
|
93 | setupSocket(socket) {
|
94 | return __awaiter(this, void 0, void 0, function* () {
|
95 | this.sockets.push(socket);
|
96 | socket.on('hello', (message) => this.onHelloMessage(message));
|
97 | socket.on('goodbye', (message) => this.onGoodbyeMessage(message));
|
98 | yield socket.start();
|
99 | });
|
100 | }
|
101 | teardown() {
|
102 | return __awaiter(this, void 0, void 0, function* () {
|
103 | for (const socket of this.sockets) {
|
104 | this.teardownSocket(socket);
|
105 | }
|
106 | this.sockets = undefined;
|
107 | });
|
108 | }
|
109 | teardownSocket(socket) {
|
110 | return __awaiter(this, void 0, void 0, function* () {
|
111 | socket.removeAllListeners('hello');
|
112 | socket.removeAllListeners('goodbye');
|
113 | yield socket.stop();
|
114 | });
|
115 | }
|
116 | onHelloMessage(message) {
|
117 | logging_1.log('Discovery#onHelloMessage - %s', message.remoteAddress);
|
118 | const device = sockets_1.mapFromMessage(message);
|
119 | if (device) {
|
120 |
|
121 | this.eventEmitter.emit('hello', device);
|
122 |
|
123 | this.requestRootDescription(message.remoteAddress, message.location);
|
124 | }
|
125 | else {
|
126 | logging_1.log('Discovery#onHelloMessage - ignore %s since mapping was unsuccessful', message.remoteAddress);
|
127 | }
|
128 | }
|
129 | onGoodbyeMessage(message) {
|
130 | logging_1.log('Discovery#onGoodbyeMessage - %s', message.remoteAddress);
|
131 | const device = sockets_1.mapFromMessage(message);
|
132 | if (device) {
|
133 | this.eventEmitter.emit('goodbye', device);
|
134 | }
|
135 | else {
|
136 | logging_1.log('Discovery#onGoodbyeMessage - ignore %s since mapping was unsuccessful', message.remoteAddress);
|
137 | }
|
138 | }
|
139 | requestRootDescription(remoteAddress, location) {
|
140 | return __awaiter(this, void 0, void 0, function* () {
|
141 | try {
|
142 | const httpClient = this.options.httpClient || new options_1.HttpClient();
|
143 | const rootDescriptionRequest = new root_descriptions_1.RootDescriptionRequest(remoteAddress, location, httpClient);
|
144 | const rootDescription = yield rootDescriptionRequest.send();
|
145 | const device = root_descriptions_1.mapFromRootDescription(rootDescription);
|
146 | if (device !== null) {
|
147 | this.eventEmitter.emit('hello', device);
|
148 | }
|
149 | }
|
150 | catch (error) {
|
151 | logging_1.log('Discovery#requestRootDescription - %o', error);
|
152 | }
|
153 | });
|
154 | }
|
155 | }
|
156 | exports.Discovery = Discovery;
|
157 |
|
\ | No newline at end of file |