/**
* @file NodeStrategy
* @copyright Monohm, Inc. 2014
*/
monohm.provide ("sensible.node.Strategy");
/**
* Implementation of Strategy for the Node platform.
*
* @class sensible.node.Strategy
*/
sensible.node.Strategy = function ()
{
sensible.Strategy.call (this);
}
monohm.inherits (sensible.node.Strategy, sensible.Strategy);
/**
* Subscribe the UDP socket to a multicast address.
*
* @param {string} inMulticastAddress - multicast address to join, eg 224.0.0.251 for MDNS
* @param {function} inCallback - function to call on completion
*/
sensible.node.Strategy.prototype.subscribe = function (inMulticastAddress, inCallback)
{
if (inCallback)
{
inCallback ();
}
}
/**
* Open the MDNS socket and join the multicast group.
* Note only one UDP socket per strategy instance.
*
* @param {function} inCallback - function to call on completion
*/
sensible.node.Strategy.prototype.open = function (inCallback)
{
// console.log ("sensible.node.Strategy.open()");
this.socket = dgram.createSocket ("udp4");
var self = this;
// note that later nodes require the address parameter
this.socket.bind
(
5353,
"0.0.0.0",
function (inError)
{
if (!inError)
{
self.socket.subscribe ("224.0.0.251");
}
inCallback (inError);
}
);
}
/**
* Close the UDP socket and bind to the specified port.
*
* @param {integer} inPort - port to which to bind, eg 5353 for MDNS
* @param {function} inCallback - function to call on completion
*/
sensible.node.Strategy.prototype.close = function ()
{
this.socket.close ();
}
/**
* Return the host name of the machine.
*
* @returns {string} host name
*/
sensible.node.Strategy.prototype.getHostName = function (inCallback)
{
inCallback (os.hostname ());
}
/**
* Return the IP address of the machine.
*
* @returns {string} IP address
*/
sensible.node.Strategy.prototype.getIPAddress = function (inCallback)
{
var address = null;
var interfaces = os.networkInterfaces ();
for (var name in interfaces)
{
var addresses = interfaces [name];
for (var i = 0; i < addresses.length; i++)
{
var address = addresses [i];
if (! address.internal)
{
if (address.family.toLowerCase () == "ipv4")
{
// should probably check for dups here, but how would we?
address = address.address;
break;
}
}
}
if (address && address.length)
{
break;
}
}
if (address == null || address.length == 0)
{
address = "127.0.0.1";
}
inCallback (address);
}
/**
* Listen for packets on the UDP socket.
*
* @param {function} inCallback - function to call on reception
*/
sensible.node.Strategy.prototype.listen = function (inCallback)
{
this.socket.on
(
"message",
function (inMessage, inRemoteInfo)
{
// convert to arraybuffer for the rest of the world
var buffer = new ArrayBuffer (inMessage.length);
var view = new Uint8Array (buffer);
for (var i = 0; i < inMessage.length; i++)
{
view [i] = inMessage [i];
}
inCallback (buffer, inRemoteInfo.address, inRemoteInfo.port);
}
);
}
/**
* Send a packet on the UDP socket.
*
* @param {ArrayBuffer} inPacket - packet
* @param {string} inRemoteAddress - remote address
* @param {port} inRemotePort - remote port
*/
sensible.node.Strategy.prototype.send = function (inPacket, inRemoteAddress, inRemotePort)
{
var view = new Uint8Array (inPacket);
var buffer = new Buffer (inPacket.byteLength);
for (var i = 0; i < inPacket.byteLength; i++)
{
buffer.writeUInt8 (view [i], i);
}
this.socket.send
(
buffer, 0, buffer.length, inRemotePort, inRemoteAddress,
function (inError, inBytes)
{
if (inError)
{
console.log ("error sending request");
console.log (inError);
}
}
);
}