service-discovery
Version:
Simple network discovery based on UDP multicast
183 lines (139 loc) • 4.26 kB
JavaScript
// Generated by CoffeeScript 1.4.0
(function() {
var Description, EventEmitter, INTERVAL, Listener, METHOD_FIND, METHOD_NOTIFY, MULTICAST_IP, MULTICAST_PORT, dgram,
__bind = function(fn, me) {
return function() {
return fn.apply(me, arguments);
};
},
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) {
for (var key in parent) {
if (__hasProp.call(parent, key)) child[key] = parent[key];
}
function ctor() {
this.constructor = child;
}
ctor.prototype = parent.prototype;
child.prototype = new ctor();
child.__super__ = parent.prototype;
return child;
};
dgram = require('dgram');
EventEmitter = require('events').EventEmitter;
METHOD_NOTIFY = 'notify';
METHOD_FIND = 'find';
INTERVAL = 2000;
MULTICAST_IP = '239.155.155.150';
MULTICAST_PORT = 22000;
/*
* Simple service discovery over UDP multicast
* Emits events with name of catched service description
* Custom event '*' catches all messages
*/
Listener = (function(_super) {
__extends(Listener, _super);
/*
* Create new instance of service finder
* @param {function(Listener) } Ready callback
* @param {number} Multicast port
* @param {string} Multicast IP
*/
function Listener(done, port, ip) {
var _this = this;
this.port = port != null ? port : MULTICAST_PORT;
this.ip = ip != null ? ip : MULTICAST_IP;
this.close = __bind(this.close, this);
this.on_message = __bind(this.on_message, this);
this.socket = dgram.createSocket('udp4');
this.socket.bind(this.port, function() {
_this.socket.addMembership(_this.ip);
if (done) {
return done(_this);
}
});
this.socket.on('message', this.on_message);
}
/*
* Listener for incoming UDP messages
*/
Listener.prototype.on_message = function(msg, rinfo) {
var ip;
msg = JSON.parse(msg.toString());
ip = rinfo.address;
this.emit(msg.name, msg.name, ip, msg.data);
return this.emit('*', msg.name, ip, msg.data);
};
/*
* Close sockets and remove all listeners
* @return {Service} itself
*/
Listener.prototype.close = function() {
this.removeAllListeners();
this.socket.close();
return this;
};
return Listener;
})(EventEmitter);
Description = (function() {
/*
* Create new instance of service description
* @param {string} Name of service
* @param {number} Multicast port
* @param {string} Multicast IP
* @param {number} Sending interval
*/
function Description(name, port, ip, interval) {
this.name = name;
this.port = port != null ? port : MULTICAST_PORT;
this.ip = ip != null ? ip : MULTICAST_IP;
if (interval == null) {
interval = INTERVAL;
}
this.close = __bind(this.close, this);
this.notify = __bind(this.notify, this);
this.attr = __bind(this.attr, this);
this.attrs = {};
this.socket = dgram.createSocket('udp4');
this.timer = setInterval(this.notify, interval);
}
/*
* Add attribute of description
* @param {string} Name of attribute.
* @param {object} Serializeable data
* @return {Service} itself
*/
Description.prototype.attr = function(name, data) {
this.attrs[name] = data;
return this;
};
/*
* Send self description to multicast group
* @return {Service} itself
*/
Description.prototype.notify = function() {
var msg;
msg = {
method: METHOD_NOTIFY,
name: this.name,
data: this.attrs,
time: Date.now()
};
msg = new Buffer(JSON.stringify(msg));
this.socket.send(msg, 0, msg.length, this.port, this.ip);
return this;
};
/*
* Close sockets and remove timer
* @return {Service} itself
*/
Description.prototype.close = function() {
this.socket.close();
clearInterval(this.timer);
return this;
};
return Description;
})();
module.exports.Listener = Listener;
module.exports.Description = Description;
}).call(this);