node package manager
Don’t reinvent the wheel. Reuse code within your team. Create a free org »

masterless-msgpack

masterless

Build Status

A fancy tcp client and server that acts as neither, and abstracts out connection deduplication between identical nodes. Uses msgpack for serialization.

Install

$ npm install masterless

Test

Run any of the following:

$ mocha
$ npm test
$ make test

Note: remember to npm install to get those yummy dev dependencies!

API

var Server = require('masterless');
 
var left = new Server('e4663c9c3f9a89112afc48389a951e09');
var right = new Server('b073a8ee09e1daca57e9d54a5efe5684');
 
left.on('listening', function(info) {
  right.connect(info);
});
 
right.on('connect', function(id) {
  right.send(id, {type: 'counter', total: 0});
});
 
left.on('message', onmessage);
right.on('message', onmessage);
 
function onmessage(sender, packet) {
  if (packet.type === 'counter') {
    packet.total % 100 === 0 && console.log('counter at', packet.total);
    this.send(sender, {type: 'counter', total: packet.total + 1});
  } else {
    console.log('unknown packet', packet);
  }
}

For more examples, see examples.

Server(id, [options])

Construct a new server object, with an id unique to context in which the server is used. Optionally specify a port to listen on.

var server = new Server('67d2cb3db178bc5ca7d9f7157e3119aa');
var serverWithPort = new Server('81358297b83f2d4d6cfa58ba5aff6180', {port: 23412});

server.connect(transport)

Connect to a remote node via a transport uri. Automatically sets the node as a keep node.

server.connect('tcp://192.168.1.64:2435');
server.connect(serverWithPort.info());

server.disconnect(id)

Disconnect from a remote via a node id.

server.disconnect('81358297b83f2d4d6cfa58ba5aff6180');

server.keep(id, [true|false])

Reconnects to the specified node if the connection dies.

server.keep('81358297b83f2d4d6cfa58ba5aff6180');

server.info()

Returns a formatted transport uri. The result of this function is included in the listening event. The info method returns null if the server has yet to initialize.

server.info(); // => 'tcp://192.168.1.64:35649' 

server.close([callback])

Ends all connections and closes the server.

server.close(function() {
  // server has been closed 
});

server.send(id, packet)

Sends a packet to one or more nodes. Returns false if unable to send for a single destination.

server.send('81358297b83f2d4d6cfa58ba5aff6180', {some: 'data'});
server.send([left.id, right.id], {some: 'other', random: 'data'});
 
server.send('not-a-valid-node', {not: 'sent'}); // returns false 

Features

Connection Deduplication

The following example will open two connections, then close exactly one as the handshake completes.

var left = new Server(...);
var right = new Server(...);
 
left.connect(right.info());
right.connect(left.info());

Multiple Dispatch

Send messages to multiple nodes with low overhead (doesn't reencode the packet).

server.send([left.id, right.id], {multiple: 'dispatch'});

Limited Reconnection

Use the keep method to specify a connection is locally important, and the server will attempt to reconnect once between disconnecting.

var left = new Server(...);
var right = new Server(...);
 
// both nodes will unilaterally try to reconnect 
right.keep(left.id);
left.connect(right.info());
 
left.once('connect', function() {
  // causes a reconnect 
  right.disconnect(left.id);
});

Caveats

  • The wire protocol is not yet stable--it is a simple protocol, but could be far more lightweight.

License

The MIT License (MIT)