Skip to content

Instantly share code, notes, and snippets.

@amirburbea
Created October 31, 2017 02:36
Show Gist options
  • Save amirburbea/d6b677665bbb98a4db97f84b36659813 to your computer and use it in GitHub Desktop.
Save amirburbea/d6b677665bbb98a4db97f84b36659813 to your computer and use it in GitHub Desktop.
const { createSocket } = require('dgram'),
{ EventEmitter } = require('events'),
regex = /^AMXB<-UUID=GlobalCache_([\dA-F]{12})>/,
MULTICAST_ADDRESS = '239.255.250.250';
class GlobalCacheDiscovery extends EventEmitter {
/**
* Discover Global Cache devices.
* @param {string} identifier - An optional Global Cache identifier to limit multicast results to.
*/
discover(identifier) {
const socket = createSocket('udp4'),
timeout = global.setTimeout(() => this.stop(), 60500),
devices = {};
socket
.on('error', error => {
this.emit('error', error);
global.clearTimeout(timeout);
this.stop();
})
.on('close', () => {
socket.removeAllListeners();
global.clearTimeout(timeout);
this.socket = undefined;
this.emit('end');
})
.on('message', (msg, rinfo) => {
const matches = regex.exec(msg);
if (!matches) {
return;
}
const [, id] = matches, { address } = rinfo;
if (devices[id] !== address) {
devices[id] = address;
if (!identifier || id === identifier) {
this.emit('device', id, devices);
}
}
if (identifier && !id.localeCompare(identifier, undefined, { sensitivity: 'accent' })) {
global.clearTimeout(timeout);
this.stop();
}
});
socket.bind(9131, undefined, () => (this.socket = socket).addMembership(MULTICAST_ADDRESS));
}
stop() {
const { socket } = this;
if (socket) {
socket.dropMembership(MULTICAST_ADDRESS);
socket.close();
}
}
}
// DEMO
const finder = new GlobalCacheDiscovery();
finder.on('device', (addedIdentifier, devices) => {
// Obviously you'll be interacting with the GC device by IP address.
// That said, a user may have multiple GC devices in their home, and the IP address may be assigned by DHCP.
// Find it again, by looking for a specific identifier (which can also be passed as a parameter to the `discover` method).
console.log(addedIdentifier, devices[addedIdentifier]);
finder.stop();
});
finder.on('end', () => finder.removeAllListeners());
finder.discover();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment