View on GitHub

Node-framed-msgpack-rpc

Fast and powerful RPC for Node

Download this project as a .zip file Download this project as a tar.gz file

Framed Msgpack RPC is an RPC system for node.js. It allows clients to call remote procedures on servers. An RPC consists of: (1) a string name; (2) an argument that is a single JSON object; (3) a reply that is also a single JSON object. Of course, those objects can be arrays, or dictionaries, so arguments and return values can be complex and interesting.

This system is a variant of the Msgpack-RPC protocol specification for node.js. Msgpack-RPC communicates binary JSON objects that are efficiently encoded and decoded with the MessagePack serialization format.

"Framed" Msgpack-RPC differs from standard Msgpack-RPC in a small way: the encoding of the length of the packet is prepended to each packet. This way, receivers can efficiently buffer data until a full packet is available to decode. In an event-based context like node.js, framing simplifies implementation, and yields a faster decoder, especially for very large messages.

By convention, RPCs are grouped into programs, which can have one or more versions. Each (prog,vers) pair then has a collection of procedures, meaning an RPC is identified unabmiguously by a (prog,vers,proc) triple. In practice, these three strings are joined with "." characters, and the dotted triple is the RPC name.

Due to framing, this protocol is not compatible with existing Msgpack-RPC systems. Support for Unix-Domain sockets is to come, but there are no plans for UDP support.

Simple Use

The simplest way to write a server is with the Server class as below:

var rpc = require('framed-msgpack-rpc');
var srv= new rpc.Server ({
    programs : {
        "myprog.1" : {
            add : function(arg, response) {
                response.result(arg.a + arg.b);
            }
        }
    },
    port : 8000 
});
srv.listen(function (err) {
    if (err) {
        console.log("Error binding: " + err);
    } else {
        console.log("Listening!");
    }
});

a corresponding client might look like:

var x = rpc.createTransport({ host: '127.0.0.1', port : 8000 });
x.connect(function (err) {
    if (err) {
        console.log("error connecting");
    } else {
        var c = new rpc.Client(x, "myprog.1");
        c.invoke('add', { a : 5, b : 4}, function(err, response) {
            if (err) {
                console.log("error in RPC: " + err);
            } else { 
                assert.equal(9, response);
            }
            x.close();
        });
    }
});

Or, equivalently, in beautiful IcedCoffeeScript:

x = rpc.createTransport { host: '127.0.0.1', port : 8000 }
await x.connect defer err
if err?
    console.log "error connecting"
else
    c = new rpc.Client x, "myprog.1"
    await c.invoke 'add', { a : 5, b : 4}, defer err, response
    if err? then console.log "error in RPC: #{err}"
    else assert.equal 9, response
    x.close()

Installation

It should work to just install with npm:

npm install -g framed-msgpack-rpc

If you install by hand, you will need to install the one dependency, which is the Msgpack C bindings, available as msgpack2 on npm:

npm install -g msgpack2

Read On!

For full API documentation, see the GitHub-hosted README file.