Fast, lightweight library for encoding and decoding JSON messages over streams.
Built using fringe
npm install --save missive
Rather than simply using newlines to delimit messages, missive
uses the
time-honored tradition of length prefixing. We think this is safer, and it
can also be quite a bit faster.
missive
exports just two functions, encode()
and parse()
. Each returns
an instance of Stream.Transform
.
Both streams pipe Buffer
instances on the way out (like pretty much
all streams), but encode
expects an object to be passed to write
.
let missive = require('missive');
// create an encoder stream
let encode = missive.encode();
// create a parser stream
let parse = missive.parse();
encode.pipe( parse ).pipe( process.stdout );
encode.write({ hello: 'world' }); // should log {"hello": "world"}
data
eventsBoth streams implement standard data
events, which emit Buffer
instances.
let missive = require('missive');
let encode = missive.encode();
let parse = missive.parse();
parse.on( 'data', buffer => {
console.log( buffer instanceof Buffer ); // true
});
encode.write({ foo: 'bar' });
message
eventThe parse
stream also implements a custom message
event for convenience.
Rather than emitting a Buffer
instance, the message
event emits a parsed
JavaScript object.
let missive = require('missive');
let encode = missive.encode();
let parse = missive.parse();
parse.on( 'message', obj => {
console.log( obj.foo ); // 'bar'
});
encode.write({ foo: 'bar' });
let net = require('net');
let missive = require('missive');
let server = net.createServer();
server.listen( 1337 );
server.on( 'connection', socket => {
let encode = missive.encode();
encode.pipe( socket );
encode.write({ hello: 'world' });
});
let net = require('net');
let missive = require('missive');
let client = net.createConnection({ port: 1337 });
client.pipe( missive.parse() ).on( 'message', obj => {
console.log( obj ); // { hello: 'world' }
});
To enable Node's zlib
compression, instantiate an encode
stream
with { deflate: true }
and a parse
stream with { inflate: true }
Note that this will incur a fairly substantial performance penalty, so compression is only advised in situations where message volume is low and saving bytes over the wire is critical.
let missive = require('missive');
let encode = missive.encode({ deflate: true });
let parse = missive.parse({ inflate: true });
parse.on( 'message', obj => {
console.log( obj.foo ); // 'bar'
});
encode.write({ foo: 'bar' });
In case you can't use missive
on one side of a socket, this is
how it encodes data:
data
be the result of JSON.stringify( object ) + '\n'
.header
be the string 'JSON'
as a utf-8 string.byteLength
be the byte length of data
as utf-8.buffer
be a new buffer of length byteLength + 8
.header
at byte offset 0
of buffer
as a UInt32LE.byteLength
at byte offset 4
of buffer
as a UInt32LE.data
at byte offset 8
of buffer
as a utf-8 string.