diff --git a/Discovery/index.ts b/Discovery/index.ts index 2da64b5..767d89b 100644 --- a/Discovery/index.ts +++ b/Discovery/index.ts @@ -4,7 +4,7 @@ import { strict as assert } from 'assert'; import { ConnectionInfo, DiscoveryMessage, DiscoveryMessageOptions, IpAddress, Units, DeviceId } from '../types'; import { sleep, WriteContext, ReadContext } from '../utils'; import { Socket, RemoteInfo, createSocket } from 'dgram'; -import { subnet, SubnetInfo } from 'ip'; +import { subnet } from 'ip'; import { networkInterfaces } from 'os'; const ANNOUNCEMENT_INTERVAL = 1000; @@ -28,7 +28,7 @@ export declare interface Discovery { export class Discovery extends EventEmitter { private socket: Socket; private address: IpAddress; - private broadcastAddress: IpAddress; + private broadcastAddresses: IpAddress[]; private options: DiscoveryMessageOptions = null; private peers: Map = new Map(); private deviceId: DeviceId = null; @@ -72,13 +72,10 @@ export class Discovery extends EventEmitter { this.socket.setBroadcast(true); const discoveryMessage = this.createDiscoveryMessage(Action.Login, this.options, port); await sleep(500); - const ips = this.findBroadcastIPs(); - const address = ips.filter((ip) => { - return ip.contains(this.address) === true; - }); - this.broadcastAddress = address.shift().broadcastAddress; + this.broadcastAddresses = this.findBroadcastIPs(); const msg = this.writeDiscoveryMessage(discoveryMessage); - this.broadcastMessage(this.socket, msg, LISTEN_PORT, this.broadcastAddress); + + this.broadcastMessage(this.socket, msg, LISTEN_PORT, this.broadcastAddresses) this.emit('announcing', discoveryMessage); Logger.debug(`Broadcast Discovery Message ${this.deviceId.string} ${discoveryMessage.source}`); this.announceTimer = setInterval( @@ -87,7 +84,7 @@ export class Discovery extends EventEmitter { this.socket, msg, LISTEN_PORT, - this.broadcastAddress + this.broadcastAddresses ); } @@ -101,7 +98,7 @@ export class Discovery extends EventEmitter { const discoveryMessage = this.createDiscoveryMessage(Action.Logout, this.options); const msg = this.writeDiscoveryMessage(discoveryMessage); - await this.broadcastMessage(this.socket, msg, LISTEN_PORT, this.broadcastAddress); + await this.broadcastMessage(this.socket, msg, LISTEN_PORT, this.broadcastAddresses); await this.socket.close(); Logger.debug('Broadcast Unannounce Message'); @@ -116,8 +113,10 @@ export class Discovery extends EventEmitter { * @param {number} port * @param {IpAddress} address */ - private async broadcastMessage(socket: Socket, msg: Buffer, port: number, address: IpAddress): Promise { - await socket.send(msg, port, address); + private async broadcastMessage(socket: Socket, msg: Buffer, port: number, address: IpAddress[]): Promise { + for (const ip of address) { + await socket.send(msg, port, ip); + } } /** @@ -220,7 +219,7 @@ export class Discovery extends EventEmitter { * Get list of Broadcast-enabled Network Interfaces * @returns {SubnetInfo[]} */ - private findBroadcastIPs(): SubnetInfo[] { + private findBroadcastIPs(): string[] { const interfaces = Object.values(networkInterfaces()); assert(interfaces.length); const ips = []; @@ -229,7 +228,7 @@ export class Discovery extends EventEmitter { for (const entry of i) { if (entry.family === 'IPv4' && entry.internal === false) { const info = subnet(entry.address, entry.netmask); - ips.push(info); + ips.push(info.broadcastAddress); } } } diff --git a/StageLinq/index.ts b/StageLinq/index.ts index 4246b2d..9c13f16 100644 --- a/StageLinq/index.ts +++ b/StageLinq/index.ts @@ -16,13 +16,49 @@ const DEFAULT_OPTIONS: StageLinqOptions = { * Main StageLinq static class. */ export class StageLinq { - static options: StageLinqOptions = DEFAULT_OPTIONS; - static readonly logger: Logger = Logger.instance; - static readonly discovery: Discovery = new Discovery(); - static readonly devices = new Devices(); - static readonly sources: Sources = new Sources(); - static readonly status: Status = new Status(); - static directory: Directory = null; + private static _options: StageLinqOptions = DEFAULT_OPTIONS; + readonly logger: Logger = Logger.instance; + private static _discovery: Discovery = null; + private static _devices: Devices = null; + private static _sources: Sources = null; + private static _status: Status = null; + private static _directory: Directory = null; + + constructor(options?: StageLinqOptions,) { + StageLinq._options = options || DEFAULT_OPTIONS; + StageLinq._discovery = new Discovery(); + StageLinq._devices = new Devices(); + StageLinq._sources = new Sources(); + StageLinq._status = new Status(); + } + + static get options() { + return this._options + } + + static get discovery() { + return this._discovery + } + + static get devices() { + return this._devices + } + + static get sources() { + return this._sources + } + + static get status() { + return this._status + } + + static get directory() { + return this._directory + } + + private static set directory(service: Directory) { + StageLinq._directory = service; + } /** @@ -43,7 +79,7 @@ export class StageLinq { /** * Connect to the StageLinq network. */ - static async connect() { + async connect() { // Initialize Discovery agent StageLinq.discovery.listen(StageLinq.options.actingAs); @@ -58,10 +94,10 @@ export class StageLinq { * Disconnect from the StageLinq network. * Close all open Servers */ - static async disconnect() { + async disconnect() { try { Logger.warn('disconnecting'); - await this.directory.stop(); + await StageLinq.directory.stop(); const services = await StageLinq.devices.getDeviceServices(); for (const service of services) { console.log(`closing ${service.name} on ${service.deviceId.string}`); diff --git a/cli/index.ts b/cli/index.ts index 4e23630..ab16ce7 100644 --- a/cli/index.ts +++ b/cli/index.ts @@ -72,20 +72,21 @@ async function main() { ], } - StageLinq.options = stageLinqOptions; + const stageLinq = new StageLinq(stageLinqOptions); - StageLinq.logger.on('error', (...args: any) => { + + stageLinq.logger.on('error', (...args: any) => { console.error(...args); }); - StageLinq.logger.on('warn', (...args: any) => { + stageLinq.logger.on('warn', (...args: any) => { console.warn(...args); args.push("\n"); }); - StageLinq.logger.on('info', (...args: any) => { + stageLinq.logger.on('info', (...args: any) => { console.info(...args); args.push("\n"); }); - StageLinq.logger.on('log', (...args: any) => { + stageLinq.logger.on('log', (...args: any) => { console.log(...args); args.push("\n"); }); @@ -276,7 +277,7 @@ async function main() { console.info('... exiting'); try { - await StageLinq.disconnect(); + await stageLinq.disconnect(); } catch (err: any) { const message = err.stack.toString(); console.error(message); @@ -284,7 +285,7 @@ async function main() { process.exit(returnCode); }); - await StageLinq.connect(); + await stageLinq.connect(); while (true) { await sleep(250); @@ -296,7 +297,7 @@ async function main() { returnCode = 1; } - await StageLinq.disconnect(); + await stageLinq.disconnect(); process.exit(returnCode); } diff --git a/cli/nowPlaying.ts b/cli/nowPlaying.ts index 1062806..40fb72e 100644 --- a/cli/nowPlaying.ts +++ b/cli/nowPlaying.ts @@ -18,8 +18,7 @@ async function main() { ], } - //const stageLinq = new StageLinq(stageLinqOptions); - StageLinq.options = stageLinqOptions + const stageLinq = new StageLinq(stageLinqOptions); async function downloadFile(sourceName: string, deviceId: DeviceId, path: string, dest?: string) { while (!StageLinq.sources.hasSource(sourceName, deviceId)) { @@ -72,7 +71,7 @@ async function main() { console.info('... exiting'); try { - await StageLinq.disconnect(); + await stageLinq.disconnect(); } catch (err: any) { const message = err.stack.toString(); console.error(message); @@ -80,7 +79,7 @@ async function main() { process.exit(returnCode); }); - await StageLinq.connect(); + await stageLinq.connect(); while (true) { await sleep(250); @@ -92,7 +91,7 @@ async function main() { returnCode = 1; } - await StageLinq.disconnect(); + await stageLinq.disconnect(); process.exit(returnCode); }