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"}
Both 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' });
The 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:
- Let
data
be the result ofJSON.stringify( object ) + '\n'
. - Let
header
be the string'JSON'
as a utf-8 string. - Let
byteLength
be the byte length ofdata
as utf-8. - Let
buffer
be a new buffer of lengthbyteLength + 8
. - Write
header
at byte offset0
ofbuffer
as a UInt32LE. - Write
byteLength
at byte offset4
ofbuffer
as a UInt32LE. - Write
data
at byte offset8
ofbuffer
as a utf-8 string.