missive
v3.0.1
Published
Fast, lightweight library for encoding and decoding JSON messages over streams.
Downloads
25
Readme
missive
Fast, lightweight library for encoding and decoding JSON messages over streams.
Built using fringe
Installing
npm install --save missive
How it works
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.
Examples
Piping data
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
events
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' });
message
event
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' });
Writing to sockets
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' });
});
Reading from sockets
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' }
});
Compression
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' });
Spec
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.