naked-websocket
Version:
Fastest WebSockets for node to node data exchange.
285 lines (204 loc) • 7.89 kB
Markdown
[![build status][travis-image]][travis-url]
[![NPM version][npm-image]][npm-url]
[![node version][node-image]][node-url]
[]: https://api.travis-ci.org/fluidecho/naked-websocket.png
[]: https://travis-ci.org/fluidecho/naked-websocket
[]: https://img.shields.io/npm/v/naked-websocket.svg?style=flat-square
[]: https://npmjs.org/package/naked-websocket
[]: https://img.shields.io/badge/node.js-%3E=_0.12-blue.svg?style=flat-square
[]: http://nodejs.org/download/
Fastest WebSockets for node to node data exchange.
Connect your back-end node.js applications with WebSockets and exchange data with any format you
wish, [JSON](https://www.npmjs.com/package/ndjson), [MsgPack](https://www.npmjs.com/package/msgpack),
none, etc.
__Why not just use socket.io or ws modules?__
You should use socket.io or ws for __Browser__ applications and Naked WebSocket for __back-end__
applications. Naked WebSocket is a __much faster__ communication link because it uses the raw _net_ or
_tls_ sockets, without Browser regard.
Naked WebSocket allows you to use any data framing (message exchange) you wish, for example
[JSON](https://www.npmjs.com/package/ndjson), [MsgPack](https://www.npmjs.com/package/msgpack), [SMP](https://github.com/smprotocol/smp-node), [AMP](https://github.com/tj/node-amp), none, or any other.
__Why not just use plain old net or tls without WebSockets?__
Because Naked WebSocket gives you a way to connect remote node.js applications via the WebSocket
Protocol, while still using the _net_ or _tls_ sockets, this is the best of both worlds! You get:
* Firewall friendly access.
* Basic Authentication.
* HTTP Headers.
* Aggree on a message exchange format EG: [JSON](https://www.npmjs.com/package/ndjson), [MsgPack](https://www.npmjs.com/package/msgpack), [SMP](https://github.com/smprotocol/smp-node), [AMP](https://github.com/tj/node-amp), etc.
* Persistent bidirectional remote node communication.
* Full control over the raw _net_ or _tls_ sockets.
__...__
_Complies with WebSocket Protocol version 13 as Sub Protocol: 'nws/' + options.version, (you choose own data framing).
This solution is not for Browser clients, but for common nodes using this module for data exchange
communication._
## Installation
```
npm install naked-websocket
```
## Example
_See examples folder._
#### Server example
```js
const nws = require('naked-websocket');
// use same options as: https://nodejs.org/api/net.html
var options = {
protocol: 'ws'
};
var server = nws.createServer(options, function(socket) {
// can examine: socket.headers
console.log('client connected');
socket.on('data', function(chunk) {
console.log(chunk.toString());
});
socket.write('hello client via net socket');
});
server.listen(8080, function() {
console.log('server bound');
});
```
```js
const nws = require('naked-websocket');
// use same options as: https://nodejs.org/api/net.html
var options = {
protocol: 'ws',
hostname: '127.0.0.1',
port: 8080,
path: '/foo/bar/?hello=world'
};
var client = nws.connect(options, function(socket) {
console.log('connected to server!');
socket.on('data', function(chunk) {
console.log(chunk.toString());
});
if ( socket.body ) { // if server body was trailing connection header, emit.
socket.emit('data', socket.body);
}
socket.write('world!');
});
```
```js
const nws = require('naked-websocket');
const fs = require('fs');
// use same options as: https://nodejs.org/api/tls.html, you need to generate own key.pem and cert.pem.
var options = {
protocol: 'wss',
slowHandshake: true, // so can do own auth.
key: fs.readFileSync(__dirname + '/keys/key.pem'),
cert: fs.readFileSync(__dirname + '/keys/cert.pem'),
rejectUnauthorized: false,
requestCert: true
};
var server = nws.createServer(options, function(socket) {
// examine: socket.headers.authorization
if ( !socket.headers.authorization ) {
socket.goodbye(401);
} else if ( socket.headers.authorization.password === 'password' ) {
socket.handshake();
} else {
socket.goodbye(401);
}
console.log('client connected');
socket.on('data', function(chunk) {
console.log(chunk.toString());
});
socket.write('hello client via tls socket');
});
server.listen(8443, function() {
console.log('server bound');
});
```
```js
const nws = require('naked-websocket');
const fs = require('fs');
// use same options as: https://nodejs.org/api/tls.html, you need to generate key.pem and cert.pem.
var options = {
protocol: 'wss',
hostname: '127.0.0.1',
port: 8443,
key: fs.readFileSync(__dirname + '/keys/key.pem'),
cert: fs.readFileSync(__dirname + '/keys/cert.pem'),
rejectUnauthorized: false,
requestCert: true,
auth: 'username:password'
};
var client = nws.connect(options, function(socket) {
console.log('connected to server!');
socket.on('data', function(chunk) {
console.log(chunk.toString());
});
if ( socket.body ) { // if server body was trailing connection header, emit.
socket.emit('data', socket.body);
}
socket.write('world!');
});
```
Naked WebSocket does not frame messages, it leaves this entirely up to each node. Nodes should deploy their own framing technique, could use [JSON](https://www.npmjs.com/package/ndjson), [MsgPack](https://www.npmjs.com/package/msgpack), [SMP](https://github.com/smprotocol/smp-node), [AMP](https://github.com/tj/node-amp), or your own.
```js
const nws = require('naked-websocket');
const msgpack = require('msgpack'); // npm install msgpack
var server = nws.createServer({protocol: 'ws'}, function(socket) {
var ms = new msgpack.Stream(socket);
ms.addListener('msg', function(m) {
console.log('server received message: ', m);
});
var payload = {foo : 'bar', num : 101, 'list-of' : [1, 2, 3], buf: new Buffer('hello')};
var msg = msgpack.pack(payload);
socket.write(msg);
}).listen(8888);
var options = {
protocol: 'ws',
hostname: '127.0.0.1',
port: 8888
};
var client = nws.connect(options, function(socket) {
if ( socket.body ) { // if server body was trailing connection header, emit.
socket.emit('data', socket.body);
}
var ms = new msgpack.Stream(socket);
ms.addListener('msg', function(m) {
console.log('client received message: ', m);
});
var payload = {hello: 'from client'};
var msg = msgpack.pack(payload);
socket.write(msg);
});
```
Can use same as: [https://nodejs.org/api/net.html](https://nodejs.org/api/net.html) (protocol: 'ws') or [https://nodejs.org/api/tls.html](https://nodejs.org/api/tls.html) (protocol: 'wss').
```
maxbuffer: 4000, // max header size, 4000 = 4 KB.
version: '0.0.1', // must be same on all peers.
protocol: 'ws', // 'wss' = secure (TLS), must be same on all peers.
slowHandshake: false, // true: if you wish to manage own auth at app level.
timedout: 15000, // how long to wait for connection, 15 seconds.
noDelay: false // true = turn nagle batching algorithm off.
```
Can set own custom headers.
```
var server = nws.createServer(options, function(socket) {
socket.handshake({headers: {Framing: 'msgpack', 'X-foo': 'bar'}});
...
```
```
var options = {
protocol: 'ws',
hostname: '127.0.0.1',
port: 8443,
headers: {
Framing: 'msgpack',
'X-Hello': 'World'
}
};
var client = nws.connect(options, function(socket) {
...
```
Choose either: [MIT](http://opensource.org/licenses/MIT) or [Apache 2.0](http://www.apache.org/licenses/LICENSE-2.0).