Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge pull request #12 from kilianc/clearstream

fixed binary support + mocha test + refactoring
  • Loading branch information...
commit 8642bebec9d44134e0118a3f6ad95120caa2f7da 2 parents 562f0e5 + 9e44b5b
Paolo Fragomeni authored
View
1  .gitignore
@@ -8,3 +8,4 @@ npm-debug.log
*.out
*.o
*.tmp
+coverage.html
View
2  .travis.yml
@@ -2,7 +2,7 @@ language: node_js
node_js:
- 0.4
- 0.6
- - 0.7
+ - 0.8
notifications:
email:
View
18 Makefile
@@ -0,0 +1,18 @@
+REPORTER = spec
+
+test:
+ @NODE_ENV=test ./node_modules/.bin/mocha test/*.test.js $(OPT) --colors --reporter $(REPORTER)
+
+test-bail:
+ $(MAKE) test OPT=--bail
+
+test-cov:
+ $(MAKE) lib-cov
+ @NSSOCKET_COV=1 $(MAKE) test REPORTER=html-cov > coverage.html
+ @open -g coverage.html
+
+lib-cov:
+ @rm -rf lib-cov
+ @jscoverage lib lib-cov
+
+.PHONY: test test-bail test-cov lib-cov
View
23 examples/bla.js
@@ -1,18 +1,15 @@
-
-var nssocket = require('../lib/nssocket');
+var nss = require('../');
var sockets = [];
-var server = nssocket.createServer(function (socket) {
-
+nss.createServer(function (socket) {
sockets.push(socket);
-
- socket.data('Connecting', function (data) {
- console.log("There are now", sockets.length);
-
- for(var i=0, l=sockets.length; i<l; i++) {
- sockets[i].send('Broadcasting', data);
+ socket.ondata('connecting', function (data) {
+ console.log('There are now', sockets.length);
+ sockets.forEach(function (s) {
+ if (socket !== socket) {
+ s.send('broadcasting', data);
}
- console.dir(data);
});
-
-}).listen(4949);
+ console.dir(data);
+ });
+}).listen(4949);
View
16 examples/foo.js
@@ -1,10 +1,8 @@
-var nssocket = require('../lib/nssocket');
-var outbound = new nssocket.NsSocket();
-
-outbound.data('Broadcasting', function (data) {
- console.log(data)
-});
+var nss = require('../');
+var outbound = nss();
-outbound.connect(4949);
-
-outbound.send('Connecting', { "random": Math.random() });
+outbound.on('data::broadcasting', function (data) {
+ console.log(data);
+}).connect(4949, function () {
+ outbound.send('connecting', { 'random' : Math.random() });
+});
View
25 examples/reconnect.js
@@ -1,29 +1,12 @@
var net = require('net'),
- nssocket = require('../lib/nssocket');
+ nss = require('../');
net.createServer(function (socket) {
- //
- // Close the underlying socket after `1000ms`
- //
setTimeout(function () {
socket.destroy();
}, 1000);
}).listen(8345);
-//
-// Create an NsSocket instance with reconnect enabled
-//
-var socket = new nssocket.NsSocket({
- reconnect: true,
- type: 'tcp4',
-});
-
-socket.on('start', function () {
- //
- // The socket will emit this event periodically
- // as it attempts to reconnect
- //
- console.dir('start');
-});
-
-socket.connect(8345);
+nss.createClient({ reconnect: true }).on('start', function () {
+ console.log('start');
+}).connect(8345);
View
26 examples/simple-protocol.js
@@ -1,4 +1,4 @@
-var nssocket = require('../lib/nssocket');
+var nss = require('../');
//
// define a simple message protocol as [<type>, <id>] and create some messages that use it.
@@ -7,12 +7,12 @@ var message1 = ['message', 'one'];
var message2 = ['message', 'two'];
//
-// Create an `nssocket` TCP server and tell the server to listen on port `6785`.
+// Create an `nss` TCP server and tell the server to listen on port `6785`.
//
-var server = nssocket.createServer(function (socket) {
+var server = nss.createServer(function (socket) {
//
- // Here `socket` will be an instance of `nssocket.NsSocket`.
+ // Here `socket` will be an instance of `NsSocket`.
// When there is a connection, send `message1` to the socket.
//
socket.send(message1);
@@ -20,32 +20,32 @@ var server = nssocket.createServer(function (socket) {
//
// listen for `message2` from the connecting socket.
//
- socket.data(message2, function (data) {
+ socket.ondata(message2, function (data) {
//
// If this callback is called, we know that the socket
// speaks our language, we will likely be provided with
// a payload. In this case `{ "foo": "bar" }`.
//
- console.dir(data);
- })
+ console.log(data);
+ });
}).listen(6785);
//
-// Create a new `nssocket` instance and then connect to the server in 1000 miliseconds.
+// Create a new `NsSocket` instance and then connect to the server in 1000 miliseconds.
//
setTimeout(function() {
- var outbound = new nssocket.NsSocket();
+ var outbound = nss();
//
- //
//
- outbound.data(message1, function () {
+ //
+ outbound.ondata(message1, function () {
outbound.send(message2, { "foo": "bar" });
});
outbound.connect(6785);
-
-}, 1000);
+
+}, 1000);
View
61 examples/verbose-protocol.js
@@ -1,37 +1,34 @@
- var nssocket = require('../lib/nssocket');
+var nss = require('../');
- //
- // Create an `nssocket` TCP server
- //
- var server = nssocket.createServer(function (socket) {
- //
- // Here `socket` will be an instance of `nssocket.NsSocket`.
- //
+//
+// Create an `nss` TCP server
+//
+var server = nss.createServer(function (socket) {
+ //
+ // Here `socket` will be an instance of `NsSocket`.
+ //
- socket.send(['drink', 'rum']);
- socket.send(['drink', 'vodka']);
+ socket.send(['drink', 'rum']);
+ socket.send(['drink', 'vodka']);
- // socket.data(['iam', 'here'], function (data) {
- // //
- // // Good! The socket speaks our language
- // // (i.e. simple 'you::there', 'iam::here' protocol)
- // //
- // // { iam: true, indeedHere: true }
- // //
- // console.dir(data);
- // });
- });
+ // socket.data(['iam', 'here'], function (data) {
+ // //
+ // // Good! The socket speaks our language
+ // // (i.e. simple 'you::there', 'iam::here' protocol)
+ // //
+ // // { iam: true, indeedHere: true }
+ // //
+ // console.dir(data)
+ // })
+});
- //
- // Tell the server to listen on port `6785` and then connect to it
- // using another NsSocket instance.
- //
- server.listen(6785);
+//
+// Tell the server to listen on port `6785` and then connect to it
+// using another NsSocket instance.
+//
+server.listen(6785);
- var outbound = new nssocket.NsSocket();
- outbound.data(['drink', '*'], function () {
- console.log('I can mix a', this.event[2], 'drink');
- //outbound.send(['iam', 'here'], { iam: true, indeedHere: true });
- });
-
- outbound.connect(6785);
+nss().ondata(['drink', '*'], function () {
+ console.log('I can mix a', this.event[2], 'drink');
+ //outbound.send(['iam', 'here'], { iam: true, indeedHere: true })
+}).connect(6785);
View
3  index.js
@@ -0,0 +1,3 @@
+module.exports = process.env.NSSOCKET_COV
+ ? require('./lib-cov/nssocket')
+ : require('./lib/nssocket');
View
535 lib-cov/nssocket.js
@@ -0,0 +1,535 @@
+/* automatically generated by JSCoverage - do not edit */
+if (typeof _$jscoverage === 'undefined') _$jscoverage = {};
+if (! _$jscoverage['nssocket.js']) {
+ _$jscoverage['nssocket.js'] = [];
+ _$jscoverage['nssocket.js'][1] = 0;
+ _$jscoverage['nssocket.js'][8] = 0;
+ _$jscoverage['nssocket.js'][10] = 0;
+ _$jscoverage['nssocket.js'][12] = 0;
+ _$jscoverage['nssocket.js'][13] = 0;
+ _$jscoverage['nssocket.js'][14] = 0;
+ _$jscoverage['nssocket.js'][15] = 0;
+ _$jscoverage['nssocket.js'][18] = 0;
+ _$jscoverage['nssocket.js'][19] = 0;
+ _$jscoverage['nssocket.js'][21] = 0;
+ _$jscoverage['nssocket.js'][23] = 0;
+ _$jscoverage['nssocket.js'][24] = 0;
+ _$jscoverage['nssocket.js'][27] = 0;
+ _$jscoverage['nssocket.js'][33] = 0;
+ _$jscoverage['nssocket.js'][34] = 0;
+ _$jscoverage['nssocket.js'][35] = 0;
+ _$jscoverage['nssocket.js'][37] = 0;
+ _$jscoverage['nssocket.js'][38] = 0;
+ _$jscoverage['nssocket.js'][39] = 0;
+ _$jscoverage['nssocket.js'][42] = 0;
+ _$jscoverage['nssocket.js'][43] = 0;
+ _$jscoverage['nssocket.js'][46] = 0;
+ _$jscoverage['nssocket.js'][47] = 0;
+ _$jscoverage['nssocket.js'][48] = 0;
+ _$jscoverage['nssocket.js'][55] = 0;
+ _$jscoverage['nssocket.js'][61] = 0;
+ _$jscoverage['nssocket.js'][62] = 0;
+ _$jscoverage['nssocket.js'][63] = 0;
+ _$jscoverage['nssocket.js'][64] = 0;
+ _$jscoverage['nssocket.js'][65] = 0;
+ _$jscoverage['nssocket.js'][69] = 0;
+ _$jscoverage['nssocket.js'][71] = 0;
+ _$jscoverage['nssocket.js'][72] = 0;
+ _$jscoverage['nssocket.js'][74] = 0;
+ _$jscoverage['nssocket.js'][75] = 0;
+ _$jscoverage['nssocket.js'][77] = 0;
+ _$jscoverage['nssocket.js'][78] = 0;
+ _$jscoverage['nssocket.js'][79] = 0;
+ _$jscoverage['nssocket.js'][80] = 0;
+ _$jscoverage['nssocket.js'][82] = 0;
+ _$jscoverage['nssocket.js'][84] = 0;
+ _$jscoverage['nssocket.js'][86] = 0;
+ _$jscoverage['nssocket.js'][89] = 0;
+ _$jscoverage['nssocket.js'][91] = 0;
+ _$jscoverage['nssocket.js'][92] = 0;
+ _$jscoverage['nssocket.js'][94] = 0;
+ _$jscoverage['nssocket.js'][95] = 0;
+ _$jscoverage['nssocket.js'][98] = 0;
+ _$jscoverage['nssocket.js'][100] = 0;
+ _$jscoverage['nssocket.js'][101] = 0;
+ _$jscoverage['nssocket.js'][104] = 0;
+ _$jscoverage['nssocket.js'][105] = 0;
+ _$jscoverage['nssocket.js'][106] = 0;
+ _$jscoverage['nssocket.js'][107] = 0;
+ _$jscoverage['nssocket.js'][110] = 0;
+ _$jscoverage['nssocket.js'][111] = 0;
+ _$jscoverage['nssocket.js'][114] = 0;
+ _$jscoverage['nssocket.js'][115] = 0;
+ _$jscoverage['nssocket.js'][117] = 0;
+ _$jscoverage['nssocket.js'][118] = 0;
+ _$jscoverage['nssocket.js'][121] = 0;
+ _$jscoverage['nssocket.js'][123] = 0;
+ _$jscoverage['nssocket.js'][124] = 0;
+ _$jscoverage['nssocket.js'][126] = 0;
+ _$jscoverage['nssocket.js'][127] = 0;
+ _$jscoverage['nssocket.js'][130] = 0;
+ _$jscoverage['nssocket.js'][131] = 0;
+ _$jscoverage['nssocket.js'][133] = 0;
+ _$jscoverage['nssocket.js'][136] = 0;
+ _$jscoverage['nssocket.js'][137] = 0;
+ _$jscoverage['nssocket.js'][138] = 0;
+ _$jscoverage['nssocket.js'][140] = 0;
+ _$jscoverage['nssocket.js'][143] = 0;
+ _$jscoverage['nssocket.js'][144] = 0;
+ _$jscoverage['nssocket.js'][147] = 0;
+ _$jscoverage['nssocket.js'][148] = 0;
+ _$jscoverage['nssocket.js'][149] = 0;
+ _$jscoverage['nssocket.js'][151] = 0;
+ _$jscoverage['nssocket.js'][154] = 0;
+ _$jscoverage['nssocket.js'][155] = 0;
+ _$jscoverage['nssocket.js'][156] = 0;
+ _$jscoverage['nssocket.js'][159] = 0;
+ _$jscoverage['nssocket.js'][160] = 0;
+ _$jscoverage['nssocket.js'][162] = 0;
+ _$jscoverage['nssocket.js'][163] = 0;
+ _$jscoverage['nssocket.js'][164] = 0;
+ _$jscoverage['nssocket.js'][167] = 0;
+ _$jscoverage['nssocket.js'][170] = 0;
+ _$jscoverage['nssocket.js'][171] = 0;
+ _$jscoverage['nssocket.js'][172] = 0;
+ _$jscoverage['nssocket.js'][174] = 0;
+ _$jscoverage['nssocket.js'][175] = 0;
+ _$jscoverage['nssocket.js'][177] = 0;
+ _$jscoverage['nssocket.js'][178] = 0;
+ _$jscoverage['nssocket.js'][181] = 0;
+ _$jscoverage['nssocket.js'][184] = 0;
+ _$jscoverage['nssocket.js'][185] = 0;
+ _$jscoverage['nssocket.js'][187] = 0;
+ _$jscoverage['nssocket.js'][188] = 0;
+ _$jscoverage['nssocket.js'][190] = 0;
+ _$jscoverage['nssocket.js'][191] = 0;
+ _$jscoverage['nssocket.js'][194] = 0;
+ _$jscoverage['nssocket.js'][197] = 0;
+ _$jscoverage['nssocket.js'][198] = 0;
+ _$jscoverage['nssocket.js'][200] = 0;
+ _$jscoverage['nssocket.js'][201] = 0;
+ _$jscoverage['nssocket.js'][202] = 0;
+ _$jscoverage['nssocket.js'][205] = 0;
+ _$jscoverage['nssocket.js'][209] = 0;
+ _$jscoverage['nssocket.js'][211] = 0;
+ _$jscoverage['nssocket.js'][212] = 0;
+ _$jscoverage['nssocket.js'][213] = 0;
+ _$jscoverage['nssocket.js'][214] = 0;
+ _$jscoverage['nssocket.js'][216] = 0;
+ _$jscoverage['nssocket.js'][217] = 0;
+ _$jscoverage['nssocket.js'][219] = 0;
+ _$jscoverage['nssocket.js'][222] = 0;
+ _$jscoverage['nssocket.js'][223] = 0;
+ _$jscoverage['nssocket.js'][224] = 0;
+ _$jscoverage['nssocket.js'][227] = 0;
+ _$jscoverage['nssocket.js'][228] = 0;
+ _$jscoverage['nssocket.js'][233] = 0;
+ _$jscoverage['nssocket.js'][234] = 0;
+ _$jscoverage['nssocket.js'][235] = 0;
+ _$jscoverage['nssocket.js'][236] = 0;
+ _$jscoverage['nssocket.js'][237] = 0;
+ _$jscoverage['nssocket.js'][238] = 0;
+ _$jscoverage['nssocket.js'][239] = 0;
+ _$jscoverage['nssocket.js'][241] = 0;
+ _$jscoverage['nssocket.js'][245] = 0;
+ _$jscoverage['nssocket.js'][246] = 0;
+ _$jscoverage['nssocket.js'][247] = 0;
+ _$jscoverage['nssocket.js'][248] = 0;
+ _$jscoverage['nssocket.js'][250] = 0;
+ _$jscoverage['nssocket.js'][251] = 0;
+ _$jscoverage['nssocket.js'][252] = 0;
+ _$jscoverage['nssocket.js'][253] = 0;
+ _$jscoverage['nssocket.js'][255] = 0;
+ _$jscoverage['nssocket.js'][256] = 0;
+ _$jscoverage['nssocket.js'][258] = 0;
+ _$jscoverage['nssocket.js'][260] = 0;
+ _$jscoverage['nssocket.js'][261] = 0;
+ _$jscoverage['nssocket.js'][264] = 0;
+ _$jscoverage['nssocket.js'][267] = 0;
+ _$jscoverage['nssocket.js'][270] = 0;
+ _$jscoverage['nssocket.js'][271] = 0;
+ _$jscoverage['nssocket.js'][272] = 0;
+ _$jscoverage['nssocket.js'][273] = 0;
+ _$jscoverage['nssocket.js'][275] = 0;
+ _$jscoverage['nssocket.js'][276] = 0;
+ _$jscoverage['nssocket.js'][278] = 0;
+ _$jscoverage['nssocket.js'][281] = 0;
+ _$jscoverage['nssocket.js'][284] = 0;
+ _$jscoverage['nssocket.js'][285] = 0;
+ _$jscoverage['nssocket.js'][288] = 0;
+ _$jscoverage['nssocket.js'][289] = 0;
+ _$jscoverage['nssocket.js'][290] = 0;
+}
+_$jscoverage['nssocket.js'][1]++;
+var net = require("net"), tls = require("tls"), util = require("util"), assert = require("chai").assert, EventEmitter2 = require("eventemitter2").EventEmitter2, bufferjoiner = require("bufferjoiner");
+_$jscoverage['nssocket.js'][8]++;
+module.exports = NsSocket;
+_$jscoverage['nssocket.js'][10]++;
+module.exports.createClient = NsSocket;
+_$jscoverage['nssocket.js'][12]++;
+module.exports.createServer = (function createServer(options, connectionListener) {
+ _$jscoverage['nssocket.js'][13]++;
+ if (! connectionListener && typeof options === "function") {
+ _$jscoverage['nssocket.js'][14]++;
+ connectionListener = options;
+ _$jscoverage['nssocket.js'][15]++;
+ options = {};
+ }
+ _$jscoverage['nssocket.js'][18]++;
+ options.type = options.type || "tcp4";
+ _$jscoverage['nssocket.js'][19]++;
+ options.delimiter = options.delimiter || "::";
+ _$jscoverage['nssocket.js'][21]++;
+ function onConnection(socket) {
+ _$jscoverage['nssocket.js'][23]++;
+ options.reconnect = false;
+ _$jscoverage['nssocket.js'][24]++;
+ connectionListener(new NsSocket(options, socket));
+}
+ _$jscoverage['nssocket.js'][27]++;
+ return options.type === "tls"? tls.createServer(options, onConnection): net.createServer(options, onConnection);
+});
+_$jscoverage['nssocket.js'][33]++;
+module.exports.data = module.exports.ondata;
+_$jscoverage['nssocket.js'][34]++;
+module.exports.unData = module.exports.offdata;
+_$jscoverage['nssocket.js'][35]++;
+module.exports.dataOnce = module.exports.oncedata;
+_$jscoverage['nssocket.js'][37]++;
+function NsSocket(options, socket) {
+ _$jscoverage['nssocket.js'][38]++;
+ if (! (this instanceof NsSocket)) {
+ _$jscoverage['nssocket.js'][39]++;
+ return new NsSocket(options, socket);
+ }
+ _$jscoverage['nssocket.js'][42]++;
+ if (! options) {
+ _$jscoverage['nssocket.js'][43]++;
+ options = socket || {};
+ }
+ _$jscoverage['nssocket.js'][46]++;
+ this.connected = false;
+ _$jscoverage['nssocket.js'][47]++;
+ this.type = options.type || "tcp4";
+ _$jscoverage['nssocket.js'][48]++;
+ this.retry = options.reconnect? {retries: 0, max: options.maxRetries || 10, wait: options.retryInterval || 5000, timeoutId: undefined}: false;
+ _$jscoverage['nssocket.js'][55]++;
+ EventEmitter2.call(this, {delimiter: options.delimiter || "::", wildcard: true, maxListeners: options.maxListeners || 10});
+ _$jscoverage['nssocket.js'][61]++;
+ if (socket) {
+ _$jscoverage['nssocket.js'][62]++;
+ this.stream = socket;
+ _$jscoverage['nssocket.js'][63]++;
+ this.socket = this.stream instanceof net.Socket? this.stream: this.stream.socket;
+ _$jscoverage['nssocket.js'][64]++;
+ this.connected = this.socket.writable && this.socket.readable || false;
+ _$jscoverage['nssocket.js'][65]++;
+ configureEvents(this);
+ }
+}
+_$jscoverage['nssocket.js'][69]++;
+util.inherits(NsSocket, EventEmitter2);
+_$jscoverage['nssocket.js'][71]++;
+NsSocket.prototype.connect = (function connect(port) {
+ _$jscoverage['nssocket.js'][72]++;
+ this.retry.timeoutId && clearTimeout(this.retry.timeoutId);
+ _$jscoverage['nssocket.js'][74]++;
+ if (! this.socket) {
+ _$jscoverage['nssocket.js'][75]++;
+ var module = this.type === "tls"? tls: net;
+ _$jscoverage['nssocket.js'][77]++;
+ this.stream = module.connect.apply(null, arguments);
+ _$jscoverage['nssocket.js'][78]++;
+ this.socket = this.stream instanceof net.Socket? this.stream: this.stream.socket;
+ _$jscoverage['nssocket.js'][79]++;
+ this.connected = this.socket.writable && this.socket.readable || false;
+ _$jscoverage['nssocket.js'][80]++;
+ this.connectionArgs = arguments;
+ _$jscoverage['nssocket.js'][82]++;
+ configureEvents(this);
+ }
+ else {
+ _$jscoverage['nssocket.js'][84]++;
+ this.socket.connect.apply(this.socket, arguments);
+ }
+ _$jscoverage['nssocket.js'][86]++;
+ return this;
+});
+_$jscoverage['nssocket.js'][89]++;
+NsSocket.prototype.write = (function write(buff) {
+ _$jscoverage['nssocket.js'][91]++;
+ if (! this.socket || ! this.connected) {
+ _$jscoverage['nssocket.js'][92]++;
+ return this.emit("error", new Error("NsSocket: sending on a bad socket"));
+ }
+ _$jscoverage['nssocket.js'][94]++;
+ this.stream.write(buff);
+ _$jscoverage['nssocket.js'][95]++;
+ return this;
+});
+_$jscoverage['nssocket.js'][98]++;
+NsSocket.prototype.send = (function send(event, data, callback) {
+ _$jscoverage['nssocket.js'][100]++;
+ if (! this.socket || ! this.connected) {
+ _$jscoverage['nssocket.js'][101]++;
+ return this.emit("error", new Error("NsSocket: sending on a bad socket"));
+ }
+ _$jscoverage['nssocket.js'][104]++;
+ var dataType = typeof data;
+ _$jscoverage['nssocket.js'][105]++;
+ if (dataType === "undefined" || dataType === "function") {
+ _$jscoverage['nssocket.js'][106]++;
+ callback = data;
+ _$jscoverage['nssocket.js'][107]++;
+ data = null;
+ }
+ _$jscoverage['nssocket.js'][110]++;
+ this.stream.write(this.createMessage(event, data), callback);
+ _$jscoverage['nssocket.js'][111]++;
+ return this;
+});
+_$jscoverage['nssocket.js'][114]++;
+NsSocket.prototype.createMessage = (function createMessage(event, data) {
+ _$jscoverage['nssocket.js'][115]++;
+ var header = new Buffer(9);
+ _$jscoverage['nssocket.js'][117]++;
+ if (typeof event === "string") {
+ _$jscoverage['nssocket.js'][118]++;
+ event = event.split(this.delimiter);
+ }
+ _$jscoverage['nssocket.js'][121]++;
+ event = Buffer(JSON.stringify(event));
+ _$jscoverage['nssocket.js'][123]++;
+ if (Buffer.isBuffer(data)) {
+ _$jscoverage['nssocket.js'][124]++;
+ header.writeInt8(1, 8);
+ }
+ else {
+ _$jscoverage['nssocket.js'][126]++;
+ data = Buffer(JSON.stringify(data));
+ _$jscoverage['nssocket.js'][127]++;
+ header.writeInt8(0, 8);
+ }
+ _$jscoverage['nssocket.js'][130]++;
+ header.writeUInt32BE(event.length, 0);
+ _$jscoverage['nssocket.js'][131]++;
+ header.writeUInt32BE(data.length, 4);
+ _$jscoverage['nssocket.js'][133]++;
+ return Buffer.concat([header, event, data], 9 + event.length + data.length);
+});
+_$jscoverage['nssocket.js'][136]++;
+NsSocket.prototype.ondata = (function (event, listener) {
+ _$jscoverage['nssocket.js'][137]++;
+ if (typeof event === "string") {
+ _$jscoverage['nssocket.js'][138]++;
+ event = event.split(this.delimiter);
+ }
+ _$jscoverage['nssocket.js'][140]++;
+ return this.on(["data"].concat(event), listener);
+});
+_$jscoverage['nssocket.js'][143]++;
+NsSocket.prototype.offdata = (function (event, listener) {
+ _$jscoverage['nssocket.js'][144]++;
+ return this.off(["data"].concat(event), listener);
+});
+_$jscoverage['nssocket.js'][147]++;
+NsSocket.prototype.oncedata = (function (event, listener) {
+ _$jscoverage['nssocket.js'][148]++;
+ if (typeof event === "string") {
+ _$jscoverage['nssocket.js'][149]++;
+ event = event.split(this.delimiter);
+ }
+ _$jscoverage['nssocket.js'][151]++;
+ return this.once(["data"].concat(event), listener);
+});
+_$jscoverage['nssocket.js'][154]++;
+NsSocket.prototype.setIdle = (function setIdle(timeout) {
+ _$jscoverage['nssocket.js'][155]++;
+ this.socket.setTimeout(timeout);
+ _$jscoverage['nssocket.js'][156]++;
+ this.timeout = timeout;
+});
+_$jscoverage['nssocket.js'][159]++;
+NsSocket.prototype.destroy = (function destroy() {
+ _$jscoverage['nssocket.js'][160]++;
+ this.removeAllListeners();
+ _$jscoverage['nssocket.js'][162]++;
+ try {
+ _$jscoverage['nssocket.js'][163]++;
+ this.socket.end();
+ _$jscoverage['nssocket.js'][164]++;
+ this.socket.destroy();
+ }
+ catch (err) {
+ }
+ _$jscoverage['nssocket.js'][167]++;
+ this.emit("destroy");
+});
+_$jscoverage['nssocket.js'][170]++;
+NsSocket.prototype.end = (function end() {
+ _$jscoverage['nssocket.js'][171]++;
+ var hadErr;
+ _$jscoverage['nssocket.js'][172]++;
+ this.connected = false;
+ _$jscoverage['nssocket.js'][174]++;
+ try {
+ _$jscoverage['nssocket.js'][175]++;
+ this.socket.end();
+ }
+ catch (err) {
+ _$jscoverage['nssocket.js'][177]++;
+ hadErr = true;
+ _$jscoverage['nssocket.js'][178]++;
+ this.emit("error", err);
+ }
+ _$jscoverage['nssocket.js'][181]++;
+ this.emit("close", hadErr);
+});
+_$jscoverage['nssocket.js'][184]++;
+NsSocket.prototype.reconnect = (function reconnect() {
+ _$jscoverage['nssocket.js'][185]++;
+ var self = this;
+ _$jscoverage['nssocket.js'][187]++;
+ this.retry.timeoutId = setTimeout((function tryReconnect() {
+ _$jscoverage['nssocket.js'][188]++;
+ self.retry.retries++;
+ _$jscoverage['nssocket.js'][190]++;
+ if (self.retry.retries >= self.retry.max) {
+ _$jscoverage['nssocket.js'][191]++;
+ return self.emit("error", new Error("Did not reconnect after maximum retries: " + self.retry.max));
+ }
+ _$jscoverage['nssocket.js'][194]++;
+ self.retry.waiting = true;
+ _$jscoverage['nssocket.js'][197]++;
+ assert.isFalse(self.connected, "before actually reconnect connected must be false");
+ _$jscoverage['nssocket.js'][198]++;
+ assert.isUndefined(self.socket, "before actually reconnect socket must be destroied");
+ _$jscoverage['nssocket.js'][200]++;
+ self.once("start", (function () {
+ _$jscoverage['nssocket.js'][201]++;
+ self.retry.waiting = false;
+ _$jscoverage['nssocket.js'][202]++;
+ self.retry.retries = 0;
+}));
+ _$jscoverage['nssocket.js'][205]++;
+ self.connect.apply(self, self.connectionArgs);
+}), this.retry.wait);
+});
+_$jscoverage['nssocket.js'][209]++;
+function configureEvents(self) {
+ _$jscoverage['nssocket.js'][211]++;
+ var eventLength = -1;
+ _$jscoverage['nssocket.js'][212]++;
+ var messageLength = -1;
+ _$jscoverage['nssocket.js'][213]++;
+ var messagetype = 0;
+ _$jscoverage['nssocket.js'][214]++;
+ var bufferJoiner = bufferjoiner();
+ _$jscoverage['nssocket.js'][216]++;
+ if (self.type === "tls") {
+ _$jscoverage['nssocket.js'][217]++;
+ self.stream.on("secureConnect", onStart);
+ }
+ else {
+ _$jscoverage['nssocket.js'][219]++;
+ self.socket.on("connect", onStart);
+ }
+ _$jscoverage['nssocket.js'][222]++;
+ function onStart() {
+ _$jscoverage['nssocket.js'][223]++;
+ self.connected = true;
+ _$jscoverage['nssocket.js'][224]++;
+ self.emit("start");
+}
+ _$jscoverage['nssocket.js'][227]++;
+ self.stream.on("data", (function onData(chunk) {
+ _$jscoverage['nssocket.js'][228]++;
+ ~ messageLength? fetchBody(chunk): fetchHeader(chunk);
+}));
+ _$jscoverage['nssocket.js'][233]++;
+ function fetchHeader(chunk) {
+ _$jscoverage['nssocket.js'][234]++;
+ if (bufferJoiner.length + chunk.length >= 9) {
+ _$jscoverage['nssocket.js'][235]++;
+ var header = bufferJoiner.add(chunk).join();
+ _$jscoverage['nssocket.js'][236]++;
+ eventLength = header.readUInt32BE(0);
+ _$jscoverage['nssocket.js'][237]++;
+ messageLength = header.readUInt32BE(4);
+ _$jscoverage['nssocket.js'][238]++;
+ messagetype = header.readInt8(8);
+ _$jscoverage['nssocket.js'][239]++;
+ fetchBody(chunk.slice(9));
+ }
+ else {
+ _$jscoverage['nssocket.js'][241]++;
+ bufferJoiner.add(chunk);
+ }
+}
+ _$jscoverage['nssocket.js'][245]++;
+ function fetchBody(chunk) {
+ _$jscoverage['nssocket.js'][246]++;
+ var raw, event, data;
+ _$jscoverage['nssocket.js'][247]++;
+ var chunkLength = chunk.length;
+ _$jscoverage['nssocket.js'][248]++;
+ var bytesLeft = (eventLength + messageLength) - bufferJoiner.length;
+ _$jscoverage['nssocket.js'][250]++;
+ if (chunkLength >= bytesLeft) {
+ _$jscoverage['nssocket.js'][251]++;
+ raw = bufferJoiner.add(chunk.slice(0, bytesLeft)).join();
+ _$jscoverage['nssocket.js'][252]++;
+ event = JSON.parse(raw.slice(0, eventLength));
+ _$jscoverage['nssocket.js'][253]++;
+ data = messagetype? raw.slice(eventLength): JSON.parse(raw.slice(eventLength).toString());
+ _$jscoverage['nssocket.js'][255]++;
+ eventLength = -1;
+ _$jscoverage['nssocket.js'][256]++;
+ messageLength = -1;
+ _$jscoverage['nssocket.js'][258]++;
+ self.emit(["data"].concat(event), data);
+ _$jscoverage['nssocket.js'][260]++;
+ if (chunkLength - bytesLeft) {
+ _$jscoverage['nssocket.js'][261]++;
+ fetchHeader(chunk.slice(bytesLeft));
+ }
+ _$jscoverage['nssocket.js'][264]++;
+ return;
+ }
+ _$jscoverage['nssocket.js'][267]++;
+ bufferJoiner.add(chunk);
+}
+ _$jscoverage['nssocket.js'][270]++;
+ self.socket.on("close", (function onClose(hadError) {
+ _$jscoverage['nssocket.js'][271]++;
+ self.socket.destroy();
+ _$jscoverage['nssocket.js'][272]++;
+ self.socket = undefined;
+ _$jscoverage['nssocket.js'][273]++;
+ self.connected = false;
+ _$jscoverage['nssocket.js'][275]++;
+ if (hadError) {
+ _$jscoverage['nssocket.js'][276]++;
+ self.emit("close", hadError, arguments[1]);
+ }
+ else {
+ _$jscoverage['nssocket.js'][278]++;
+ self.emit("close");
+ }
+ _$jscoverage['nssocket.js'][281]++;
+ self.retry && self.reconnect();
+}));
+ _$jscoverage['nssocket.js'][284]++;
+ self.socket.on("error", (function (err) {
+ _$jscoverage['nssocket.js'][285]++;
+ ! self.retry && self.emit("error", err || new Error("An Unknown Error occured"));
+}));
+ _$jscoverage['nssocket.js'][288]++;
+ self.socket.on("timeout", (function onIdle() {
+ _$jscoverage['nssocket.js'][289]++;
+ self.emit("idle");
+ _$jscoverage['nssocket.js'][290]++;
+ self.timeout && self.socket.setTimeout(this.timeout);
+}));
+}
+_$jscoverage['nssocket.js'].source = ["var net = require('net'),"," tls = require('tls'),"," util = require('util'),"," assert = require('chai').assert,"," EventEmitter2 = require('eventemitter2').EventEmitter2,"," bufferjoiner = require('bufferjoiner');","","module.exports = NsSocket;","","module.exports.createClient = NsSocket;","","module.exports.createServer = function createServer(options, connectionListener) {"," if (!connectionListener &amp;&amp; typeof options === 'function') {"," connectionListener = options;"," options = {};"," }",""," options.type = options.type || 'tcp4';"," options.delimiter = options.delimiter || '::';",""," function onConnection (socket) {"," // inbounds sockets can not reconnect by definition"," options.reconnect = false;"," connectionListener(new NsSocket(options, socket));"," }",""," return options.type === 'tls'"," ? tls.createServer(options, onConnection)"," : net.createServer(options, onConnection);","};","","// retro compatibility fixes","module.exports.data = module.exports.ondata;","module.exports.unData = module.exports.offdata;","module.exports.dataOnce = module.exports.oncedata;","","function NsSocket(options, socket) {"," if (!(this instanceof NsSocket)) {"," return new NsSocket(options, socket);"," }",""," if (!options) {"," options = socket || {};"," }",""," this.connected = false;"," this.type = options.type || 'tcp4';"," this.retry = options.reconnect ? {"," retries: 0,"," max: options.maxRetries || 10,"," wait: options.retryInterval || 5000,"," timeoutId: undefined"," } : false;",""," EventEmitter2.call(this, {"," delimiter: options.delimiter || '::',"," wildcard: true,"," maxListeners: options.maxListeners || 10"," });",""," if (socket) {"," this.stream = socket;"," this.socket = this.stream instanceof net.Socket ? this.stream : this.stream.socket;"," this.connected = this.socket.writable &amp;&amp; this.socket.readable || false;"," configureEvents(this);"," }","}","","util.inherits(NsSocket, EventEmitter2);","","NsSocket.prototype.connect = function connect(port) {"," this.retry.timeoutId &amp;&amp; clearTimeout(this.retry.timeoutId);",""," if (!this.socket) {"," var module = this.type === 'tls' ? tls : net;",""," this.stream = module.connect.apply(null, arguments);"," this.socket = this.stream instanceof net.Socket ? this.stream : this.stream.socket;"," this.connected = this.socket.writable &amp;&amp; this.socket.readable || false;"," this.connectionArgs = arguments;",""," configureEvents(this);"," } else {"," this.socket.connect.apply(this.socket, arguments);"," }"," return this;","};","","NsSocket.prototype.write = function write(buff) {"," // if we aren't connected/socketed, then error"," if (!this.socket || !this.connected) {"," return this.emit('error', new Error('NsSocket: sending on a bad socket'));"," }"," this.stream.write(buff);"," return this;","};","","NsSocket.prototype.send = function send(event, data, callback) {"," // if we aren't connected/socketed, then error"," if (!this.socket || !this.connected) {"," return this.emit('error', new Error('NsSocket: sending on a bad socket'));"," }",""," var dataType = typeof data;"," if (dataType === 'undefined' || dataType === 'function') {"," callback = data;"," data = null;"," }",""," this.stream.write(this.createMessage(event, data), callback);"," return this;","};","","NsSocket.prototype.createMessage = function createMessage(event, data) {"," var header = new Buffer(9);",""," if (typeof event === 'string') {"," event = event.split(this.delimiter);"," }",""," event = Buffer(JSON.stringify(event));",""," if (Buffer.isBuffer(data)) {"," header.writeInt8(1, 8);"," } else {"," data = Buffer(JSON.stringify(data));"," header.writeInt8(0, 8);"," }",""," header.writeUInt32BE(event.length, 0);"," header.writeUInt32BE(data.length, 4);",""," return Buffer.concat([header, event, data], 9 + event.length + data.length);","};","","NsSocket.prototype.ondata = function (event, listener) {"," if (typeof event === 'string') {"," event = event.split(this.delimiter);"," }"," return this.on(['data'].concat(event), listener);","};","","NsSocket.prototype.offdata = function (event, listener) {"," return this.off(['data'].concat(event), listener);","};","","NsSocket.prototype.oncedata = function (event, listener) {"," if (typeof event === 'string') {"," event = event.split(this.delimiter);"," }"," return this.once(['data'].concat(event), listener);","};","","NsSocket.prototype.setIdle = function setIdle(timeout) {"," this.socket.setTimeout(timeout);"," this.timeout = timeout;","};","","NsSocket.prototype.destroy = function destroy() {"," this.removeAllListeners();",""," try {"," this.socket.end();"," this.socket.destroy();"," } catch (err) {}",""," this.emit('destroy');","};","","NsSocket.prototype.end = function end() {"," var hadErr;"," this.connected = false;",""," try {"," this.socket.end();"," } catch (err) {"," hadErr = true;"," this.emit('error', err);"," }",""," this.emit('close', hadErr);","};","","NsSocket.prototype.reconnect = function reconnect() {"," var self = this;",""," this.retry.timeoutId = setTimeout(function tryReconnect() {"," self.retry.retries ++;",""," if (self.retry.retries &gt;= self.retry.max) {"," return self.emit('error', new Error('Did not reconnect after maximum retries: ' + self.retry.max));"," }",""," self.retry.waiting = true;",""," // here for debugging reasons"," assert.isFalse(self.connected, 'before actually reconnect connected must be false');"," assert.isUndefined(self.socket, 'before actually reconnect socket must be destroied');",""," self.once('start', function () {"," self.retry.waiting = false;"," self.retry.retries = 0;"," });",""," self.connect.apply(self, self.connectionArgs);"," }, this.retry.wait);","};","","function configureEvents(self) {"," // parsing holders"," var eventLength = -1;"," var messageLength = -1;"," var messagetype = 0;"," var bufferJoiner = bufferjoiner();",""," if (self.type === 'tls') {"," self.stream.on('secureConnect', onStart);"," } else {"," self.socket.on('connect', onStart);"," }",""," function onStart() {"," self.connected = true;"," self.emit('start');"," }",""," self.stream.on('data', function onData(chunk) {"," ~messageLength"," ? fetchBody(chunk)"," : fetchHeader(chunk);"," });",""," function fetchHeader(chunk) {"," if (bufferJoiner.length + chunk.length &gt;= 9) {"," var header = bufferJoiner.add(chunk).join();"," eventLength = header.readUInt32BE(0);"," messageLength = header.readUInt32BE(4);"," messagetype = header.readInt8(8);"," fetchBody(chunk.slice(9));"," } else {"," bufferJoiner.add(chunk);"," }"," }",""," function fetchBody(chunk) {"," var raw, event, data;"," var chunkLength = chunk.length;"," var bytesLeft = (eventLength + messageLength) - bufferJoiner.length;",""," if (chunkLength &gt;= bytesLeft) {"," raw = bufferJoiner.add(chunk.slice(0, bytesLeft)).join();"," event = JSON.parse(raw.slice(0, eventLength));"," data = messagetype ? raw.slice(eventLength) : JSON.parse(raw.slice(eventLength).toString());",""," eventLength = -1;"," messageLength = -1;",""," self.emit(['data'].concat(event), data);",""," if (chunkLength - bytesLeft) {"," fetchHeader(chunk.slice(bytesLeft));"," }",""," return;"," }",""," bufferJoiner.add(chunk);"," }",""," self.socket.on('close', function onClose(hadError) {"," self.socket.destroy();"," self.socket = undefined;"," self.connected = false;",""," if (hadError) {"," self.emit('close', hadError, arguments[1]);"," } else {"," self.emit('close');"," }",""," self.retry &amp;&amp; self.reconnect();"," });",""," self.socket.on('error', function (err) {"," !self.retry &amp;&amp; self.emit('error', err || new Error('An Unknown Error occured'));"," });",""," self.socket.on('timeout', function onIdle() {"," self.emit('idle');"," self.timeout &amp;&amp; self.socket.setTimeout(this.timeout);"," });","}"];
View
105 lib/common.js
@@ -1,105 +0,0 @@
-/*
- * common.js
- *
- * (C) 2011, Nodejitsu Inc.
- */
-
-var fs = require('fs'),
- tls = require('tls'),
- net = require('net'),
- crypto = require('crypto');
-
-exports.createSocket = function (options) {
- options = options || {};
- options.type = options.type || 'tcp4';
-
- return options.type === 'tls'
- ? exports.createTlsSocket(options)
- : new net.Socket(options);
-};
-
-//
-// ### function createTlsSocket (options)
-// #### @options {Object} Tls options like in tls.js
-// #### Should behave like tls.connect, except it just creates the socket like net.Socket
-// #### Also has a function called 'connect' that will allow` it to connect to a remote host
-// this is a rip of tls.js's connect
-//
-exports.createTlsSocket = function(options) {
- var self = this;
-
- //
- // Setup the TLS connection over the existing TCP connection:
- //
- // 1. Create a new instance of `net.Socket`.
- // 2. Create a new set of credentials with `options`.
- // 3. Create the TLS pair
- // 4. Pipe the TLS pair to the TCP socket
- //
- var socket = new net.Stream({ type: 'tcp4' });
-
- function setupTlsPipe () {
- var sslcontext = crypto.createCredentials(options),
- pair = tls.createSecurePair(sslcontext, false),
- cleartext = pipe(pair, socket);
-
- pair.on('secure', function() {
- var verifyError = pair.ssl.verifyError();
-
- if (verifyError) {
- cleartext.authorized = false;
- cleartext.authorizationError = verifyError;
- }
- else {
- cleartext.authorized = true;
- }
- });
-
- //
- // Setup the cleartext stream to have a `.connect()` method
- // which passes through to the underlying TCP socket.
- //
- socket.cleartext = cleartext;
- cleartext._controlReleased = true;
- }
-
- socket.on('connect', setupTlsPipe);
-
- return socket;
-};
-
-//
-// helper function for createTlsSocket
-//
-function pipe(pair, socket) {
- pair.encrypted.pipe(socket);
- socket.pipe(pair.encrypted);
-
- pair.fd = socket.fd;
- var cleartext = pair.cleartext;
- cleartext.socket = socket;
- cleartext.encrypted = pair.encrypted;
- cleartext.authorized = false;
-
- function onerror(e) {
- if (cleartext._controlReleased) {
- cleartext.emit('error', e);
- }
- }
-
- function onclose() {
- socket.removeListener('error', onerror);
- socket.removeListener('close', onclose);
- socket.removeListener('timeout', ontimeout);
- }
-
- function ontimeout() {
- cleartext.emit('timeout');
- }
-
- socket.on('error', onerror);
- socket.on('close', onclose);
- socket.on('timeout', ontimeout);
-
- return cleartext;
-}
View
636 lib/nssocket.js
@@ -1,155 +1,125 @@
-/*
- * nssocket.js - Wraps a TLS/TCP socket to emit namespace events also auto-buffers.
- *
- * (C) 2011, Nodejitsu Inc.
- *
- */
-
var net = require('net'),
tls = require('tls'),
util = require('util'),
- events2 = require('eventemitter2'),
- BufferJoiner = require('bufferjoiner'),
- common = require('./common');
-
-//
-// ### function NsSocket (socket, options)
-// #### @socket {Object} TCP or TLS 'socket' either from a 'connect' 'new' or from a server
-// #### @options {Object} Options for this NsSocket
-// NameSpace Socket, NsSocket, is a thin wrapper above TLS/TCP.
-// It provides automatic buffering and name space based data emits.
-//
-var NsSocket = exports.NsSocket = function (socket, options) {
- if (!(this instanceof NsSocket)) {
- return new NsSocket(socket, options);
- }
+ assert = require('chai').assert,
+ EventEmitter2 = require('eventemitter2').EventEmitter2,
+ bufferjoiner = require('bufferjoiner');
- //
- // If there is no Socket instnace to wrap,
- // create one.
- //
- if (!options) {
- options = socket;
- socket = common.createSocket(options);
- }
-
- //
- // Options should be
- //
- // {
- // type : 'tcp' or 'tls',
- // delimiter : '::', delimiter that separates between segments
- // msgLength : 3 //number of segments in a complete message
- // }
- //
- options = options || {};
-
- var self = this,
- startName;
-
- //
- // Setup underlying socket state.
- //
- this.socket = socket;
- this.connected = options.connected || socket.writable && socket.readable || false;
-
- //
- // Setup reconnect options.
- //
- this._reconnect = options.reconnect || false;
- this.retry = {
- retries: 0,
- max: options.maxRetries || 10,
- interval: options.retryInterval || 5000,
- wait: options.retryInterval || 5000
- };
-
- //
- // Setup default instance variables.
- //
- this._options = options;
- this._type = options.type || 'tcp4',
- this._delimiter = options.delimiter || '::';
-
- events2.EventEmitter2.call(this, {
- delimiter: this._delimiter,
- wildcard: true,
- maxListeners: options.maxListeners || 10
- });
+module.exports = NsSocket;
- // Initializing parsing holders
- this._eventLength = -1;
- this._messageLength = -1;
- this._messagetype = 0;
- this._bufferJoiner = new BufferJoiner();
+module.exports.createClient = NsSocket;
- this._setup();
-};
-
-//
-// Inherit from `events2.EventEmitter2`.
-//
-util.inherits(NsSocket, events2.EventEmitter2);
-
-//
-// ### function createServer (options, connectionListener)
-// #### @options {Object} **Optional**
-// Creates a new TCP/TLS server which wraps every incoming connection
-// in an instance of `NsSocket`.
-//
-exports.createServer = function createServer(options, connectionListener) {
+module.exports.createServer = function createServer(options, connectionListener) {
if (!connectionListener && typeof options === 'function') {
connectionListener = options;
options = {};
}
-
- options.type = options.type || 'tcp4';
+
+ options.type = options.type || 'tcp4';
options.delimiter = options.delimiter || '::';
-
+
function onConnection (socket) {
- //
- // Incoming socket connections cannot reconnect
- // by definition.
- //
+ // inbounds sockets can not reconnect by definition
options.reconnect = false;
- connectionListener(new NsSocket(socket, options));
- }
-
+ connectionListener(new NsSocket(options, socket));
+ }
+
return options.type === 'tls'
? tls.createServer(options, onConnection)
: net.createServer(options, onConnection);
};
-//
-// ### function send (data, callback)
-// #### @event {Array|string} The array (or string) that holds the event name
-// #### @data {Literal|Object} The data to be sent with the event.
-// #### @callback {Function} the callback function when send is done sending
-// The send function follows write/send rules for TCP/TLS/UDP
-// in that the callback is called when sending is complete, not when delivered
-//
-NsSocket.prototype.send = function send(event, data, callback) {
- var dataType = typeof data,
- header = new Buffer(9),
- message;
+// retro compatibility fixes
+module.exports.data = module.exports.ondata;
+module.exports.unData = module.exports.offdata;
+module.exports.dataOnce = module.exports.oncedata;
+
+function NsSocket(options, socket) {
+ if (!(this instanceof NsSocket)) {
+ return new NsSocket(options, socket);
+ }
+
+ if (!options) {
+ options = socket || {};
+ }
+
+ this.connected = false;
+ this.type = options.type || 'tcp4';
+ this.retry = options.reconnect ? {
+ retries: 0,
+ max: options.maxRetries || 10,
+ wait: options.retryInterval || 5000,
+ timeoutId: undefined
+ } : false;
+
+ EventEmitter2.call(this, {
+ delimiter: options.delimiter || '::',
+ wildcard: true,
+ maxListeners: options.maxListeners || 10
+ });
+
+ if (socket) {
+ this.stream = socket;
+ this.socket = this.stream instanceof net.Socket ? this.stream : this.stream.socket;
+ this.connected = this.socket.writable && this.socket.readable || false;
+ configureEvents(this);
+ }
+}
+
+util.inherits(NsSocket, EventEmitter2);
+NsSocket.prototype.connect = function connect(port) {
+ this.retry.timeoutId && clearTimeout(this.retry.timeoutId);
+
+ if (!this.socket) {
+ var module = this.type === 'tls' ? tls : net;
+
+ this.stream = module.connect.apply(null, arguments);
+ this.socket = this.stream instanceof net.Socket ? this.stream : this.stream.socket;
+ this.connected = this.socket.writable && this.socket.readable || false;
+ this.connectionArgs = arguments;
+
+ configureEvents(this);
+ } else {
+ this.socket.connect.apply(this.socket, arguments);
+ }
+ return this;
+};
+
+NsSocket.prototype.write = function write(buff) {
// if we aren't connected/socketed, then error
if (!this.socket || !this.connected) {
return this.emit('error', new Error('NsSocket: sending on a bad socket'));
}
+ this.stream.write(buff);
+ return this;
+};
- // rebinds
- if (typeof event === 'string') {
- event = event.split(this._delimiter);
+NsSocket.prototype.send = function send(event, data, callback) {
+ // if we aren't connected/socketed, then error
+ if (!this.socket || !this.connected) {
+ return this.emit('error', new Error('NsSocket: sending on a bad socket'));
}
- event = Buffer(JSON.stringify(event));
-
+ var dataType = typeof data;
if (dataType === 'undefined' || dataType === 'function') {
callback = data;
data = null;
}
+ this.stream.write(this.createMessage(event, data), callback);
+ return this;
+};
+
+NsSocket.prototype.createMessage = function createMessage(event, data) {
+ var header = new Buffer(9);
+
+ if (typeof event === 'string') {
+ event = event.split(this.delimiter);
+ }
+
+ event = Buffer(JSON.stringify(event));
+
if (Buffer.isBuffer(data)) {
header.writeInt8(1, 8);
} else {
@@ -160,379 +130,163 @@ NsSocket.prototype.send = function send(event, data, callback) {
header.writeUInt32BE(event.length, 0);
header.writeUInt32BE(data.length, 4);
- message = Buffer.concat([header, event, data], 9 + event.length + data.length);
-
- // now actually write to the socket
- if (this.socket.cleartext) {
- this.socket.cleartext.write(message, callback);
- } else {
- this.socket.write(message, callback);
- }
+ return Buffer.concat([header, event, data], 9 + event.length + data.length);
};
-//
-// ### function data (event, callback)
-// #### @event {Array|string} Namespaced `data` event to listen to.
-// #### @callback {function} Continuation to call when the event is raised.
-// Shorthand function for listening to `['data', '*']` events.
-//
-NsSocket.prototype.data = function (event, callback) {
+NsSocket.prototype.ondata = function (event, listener) {
if (typeof event === 'string') {
- event = event.split(this._delimiter);
+ event = event.split(this.delimiter);
}
-
- this.on(['data'].concat(event), callback);
+ return this.on(['data'].concat(event), listener);
};
-NsSocket.prototype.undata = function (event, listener) {
- this.off(['data'].concat(event), listener);
+NsSocket.prototype.offdata = function (event, listener) {
+ return this.off(['data'].concat(event), listener);
};
-//
-// ### function data (event, callback)
-// #### @event {Array|string} Namespaced `data` event to listen to once.
-// #### @callback {function} Continuation to call when the event is raised.
-// Shorthand function for listening to `['data', '*']` events once.
-//
-NsSocket.prototype.dataOnce = function (event, callback) {
+NsSocket.prototype.oncedata = function (event, listener) {
if (typeof event === 'string') {
- event = event.split(this._delimiter);
+ event = event.split(this.delimiter);
}
-
- this.once(['data'].concat(event), callback);
+ return this.once(['data'].concat(event), listener);
};
-//
-// ### function setIdle (time, callback)
-// #### @time {Integer} how often to emit idle
-// Set the idle/timeout timer
-//
-NsSocket.prototype.setIdle = function setIdle(time) {
- this.socket.setTimeout(time);
- this._timeout = time;
+NsSocket.prototype.setIdle = function setIdle(timeout) {
+ this.socket.setTimeout(timeout);
+ this.timeout = timeout;
};
-//
-// ### function destroy (void)
-// #### forcibly destroys this nsSocket, unregister socket, remove all callbacks
-//
NsSocket.prototype.destroy = function destroy() {
- // this should be forcibly remove EVERY listener
this.removeAllListeners();
- if (this.socket) {
- try {
- this.socket.end(); // send FIN
- this.socket.destroy(); // make sure fd's are gone
- }
- catch (ex) {
- // do nothing on errors
- }
- }
-
- // clear buffer
- this.data = '';
+ try {
+ this.socket.end();
+ this.socket.destroy();
+ } catch (err) {}
+
this.emit('destroy');
};
-//
-// ### function end (void)
-// #### closes the underlying socket, recommend you call destroy after
-//
NsSocket.prototype.end = function end() {
var hadErr;
this.connected = false;
- if (this.socket) {
- try {
- this.socket.end();
- }
- catch (ex) {
- this.emit('error', ex);
- hadErr = true;
- return;
- }
-
- this.socket = null;
+ try {
+ this.socket.end();
+ } catch (err) {
+ hadErr = true;
+ this.emit('error', err);
}
-
- return this.emit('close', hadErr || undefined);
+
+ this.emit('close', hadErr);
};
-//
-// ### function connect (port[, host, callback])
-// A passthrough to the underlying socket's connect function
-//
-NsSocket.prototype.connect = function connect(/*port, host, callback*/) {
- var args = Array.prototype.slice.call(arguments),
- self = this,
- callback,
- host,
- port;
-
- args.forEach(function handle(arg) {
- var type = typeof arg;
- switch (type) {
- case 'number':
- port = arg;
- break;
- case 'string':
- host = arg;
- break;
- case 'function':
- callback = arg;
- break;
- default:
- self.emit('error', new Error('bad argument to connect'));
- break;
- }
- });
+NsSocket.prototype.reconnect = function reconnect() {
+ var self = this;
- host = host || '127.0.0.1';
- this.port = port || this.port;
- this.host = host || this.host;
- args = this.port ? [this.port, this.host] : [this.host];
-
- if (callback) {
- args.push(callback);
- }
-
- if (['tcp4', 'tls'].indexOf(this._type) === -1) {
- return this.emit('error', new Error('Unknown Socket Type'));
- }
+ this.retry.timeoutId = setTimeout(function tryReconnect() {
+ self.retry.retries ++;
- var errHandlers = self.listeners('error');
+ if (self.retry.retries >= self.retry.max) {
+ return self.emit('error', new Error('Did not reconnect after maximum retries: ' + self.retry.max));
+ }
- if (errHandlers.length > 0) {
- //
- // copy the last error from nssocker onto the error event.
- //
- self.socket._events.error = errHandlers[errHandlers.length-1];
- }
+ self.retry.waiting = true;
- this.connected = true;
- this.socket.connect.apply(this.socket, args);
-};
+ // here for debugging reasons
+ assert.isFalse(self.connected, 'before actually reconnect connected must be false');
+ assert.isUndefined(self.socket, 'before actually reconnect socket must be destroied');
-//
-// ### function reconnect ()
-// Attempts to reconnect the current socket on `close` or `error`.
-// This instance will attempt to reconnect until `this.retry.max` is reached,
-// with an interval increasing by powers of 10.
-//
-NsSocket.prototype.reconnect = function reconnect() {
- var self = this;
-
- //
- // Helper function containing the core reconnect logic
- //
- function doReconnect() {
- //
- // Cleanup and recreate the socket associated
- // with this instance.
- //
- self.retry.waiting = true;
- self.socket.removeAllListeners();
- self.socket = common.createSocket(self._options);
-
- //
- // Cleanup reconnect logic once the socket connects
- //
- self.socket.once('connect', function () {
+ self.once('start', function () {
self.retry.waiting = false;
self.retry.retries = 0;
});
-
- //
- // Attempt to reconnect the socket
- //
- self._setup();
- self.connect();
- }
-
- //
- // Helper function which attempts to retry if
- // it is less than the maximum
- //
- function tryReconnect() {
- self.retry.retries++;
- if (self.retry.retries >= self.retry.max) {
- return self.emit('error', new Error('Did not reconnect after maximum retries: ' + self.retry.max));
- }
-
- doReconnect();
- }
-
- this.retry.wait = this.retry.interval * Math.pow(10, this.retry.retries);
- setTimeout(tryReconnect, this.retry.wait);
+
+ self.connect.apply(self, self.connectionArgs);
+ }, this.retry.wait);
};
-//
-// ### @private function _setup ()
-// Sets up the underlying socket associate with this instance.
-//
-NsSocket.prototype._setup = function () {
- var self = this,
- startName;
-
- //
- // Because of how the code node.js `tls` module works, we have
- // to separate some bindings. The main difference is on
- // connection, some socket activities.
- //
- if (this._type === 'tcp4') {
- startName = 'connect';
-
- this.socket.on('data', this._onData.bind(this));
-
- // create a stub for the setKeepAlive functionality
- this.setKeepAlive = function () {
- self.socket.setKeepAlive.apply(self.socket, arguments);
- };
- }
- else if (this._type === 'tls') {
- startName = 'secureConnection';
- this.socket.once('connect', function () {
- self.socket.cleartext.on('data', self._onData.bind(self));
- });
+function configureEvents(self) {
+ // parsing holders
+ var eventLength = -1;
+ var messageLength = -1;
+ var messagetype = 0;
+ var bufferJoiner = bufferjoiner();
- // create a stub for the setKeepAlive functionality
- this.setKeepAlive = function () {
- self.socket.socket.setKeepAlive.apply(self.socket.socket, arguments);
- };
+ if (self.type === 'tls') {
+ self.stream.on('secureConnect', onStart);
+ } else {
+ self.socket.on('connect', onStart);
}
- else {
- // bad arguments, so throw an error
- this.emit('error', new Error('Bad Option Argument [type]'));
- return null;
+
+ function onStart() {
+ self.connected = true;
+ self.emit('start');
}
- // make sure we listen to the underlying socket
- this.socket.on(startName, this._onStart.bind(this));
- this.socket.on('close', this._onClose.bind(this));
+ self.stream.on('data', function onData(chunk) {
+ ~messageLength
+ ? fetchBody(chunk)
+ : fetchHeader(chunk);
+ });
- if (this.socket.socket) {
- //
- // otherwise we get a error passed from net.js
- // they need to backport the fix from v5 to v4
- //
- this.socket.socket.on('error', this._onError.bind(this));
+ function fetchHeader(chunk) {
+ if (bufferJoiner.length + chunk.length >= 9) {
+ var header = bufferJoiner.add(chunk).join();
+ eventLength = header.readUInt32BE(0);
+ messageLength = header.readUInt32BE(4);
+ messagetype = header.readInt8(8);
+ fetchBody(chunk.slice(9));
+ } else {
+ bufferJoiner.add(chunk);
+ }
}
- this.socket.on('error', this._onError.bind(this));
- this.socket.on('timeout', this._onIdle.bind(this));
-};
+ function fetchBody(chunk) {
+ var raw, event, data;
+ var chunkLength = chunk.length;
+ var bytesLeft = (eventLength + messageLength) - bufferJoiner.length;
-//
-// ### @private function _onStart ()
-// Emits a start event when the underlying socket finish connecting
-// might be used to do other activities.
-//
-NsSocket.prototype._onStart = function _onStart() {
- this.emit('start');
-};
+ if (chunkLength >= bytesLeft) {
+ raw = bufferJoiner.add(chunk.slice(0, bytesLeft)).join();
+ event = JSON.parse(raw.slice(0, eventLength));
+ data = messagetype ? raw.slice(eventLength) : JSON.parse(raw.slice(eventLength).toString());
-//
-// ### @private function _onData (message)
-// #### @chunk {Buffer} binary chunk from the data event of the socket
-// Messages are assumed to be formatted properly (if using nssocket to send)
-// We assume messages arrive in order.
-//
-NsSocket.prototype._onData = function _onData(chunk) {
- ~this._incomingMessageLength ? this._fetchHeader(chunk) : this._fetchBody(chunk);
-};
+ eventLength = -1;
+ messageLength = -1;
-//
-// ### @private function _fetchHeader (chunk)
-// #### @chunk {Buffer} binary chunk from the data event of the socket
-// Buffers and parse the header of the message
-//
-NsSocket.prototype._fetchHeader = function _fetchHeader(chunk) {
- var header
-
- if (this._bufferJoiner.length + chunk.length >= 9) {
- header = this._bufferJoiner.add(chunk).join();
- this._eventLength = header.readUInt32BE(0);
- this._messageLength = header.readUInt32BE(4);
- this._messagetype = header.readInt8(8);
- this._fetchBody(chunk.slice(9));
- } else {
- this._bufferJoiner.add(chunk);
- }
-};
+ self.emit(['data'].concat(event), data);
-//
-// ### @private function _fetchBody (chunk)
-// #### @chunk {Buffer} binary chunk from the data event of the socket
-// Buffers and parse the body of the message, when ready
-// emits a data::* event
-//
-NsSocket.prototype._fetchBody = function _fetchBody(chunk) {
- var raw, event, data;
- var chunkLength = chunk.length;
- var bytesLeft = (this._eventLength + this._messageLength) - this._bufferJoiner.length;
-
- if (chunkLength >= bytesLeft) {
- raw = this._bufferJoiner.add(chunk.slice(0, bytesLeft)).join();
- event = JSON.parse(raw.slice(0, this._eventLength));
- data = this._messagetype ? raw.slice(this._eventLength) : JSON.parse(raw.slice(this._eventLength).toString());
-
- this._eventLength = -1;
- this._messageLength = -1;
- this.emit(['data'].concat(event), data);
-
- if (chunkLength - bytesLeft) {
- process.nextTick(this._fetchHeader.bind(this, chunk.slice(bytesLeft)));
+ if (chunkLength - bytesLeft) {
+ fetchHeader(chunk.slice(bytesLeft));
+ }
+
+ return;
}
- return;
+ bufferJoiner.add(chunk);
}
- this._bufferJoiner.add(chunk);
-};
+ self.socket.on('close', function onClose(hadError) {
+ self.socket.destroy();
+ self.socket = undefined;
+ self.connected = false;
-//
-// ### @private function _onClose (hadError)
-// #### @hadError {Boolean} true if there was an error, which then include the
-// actual error included by the underlying socket
-//
-NsSocket.prototype._onClose = function _onClose(hadError) {
- if (hadError) {
- this.emit('close', hadError, arguments[1]);
- }
- else {
- this.emit('close');
- }
-
- this.connected = false;
- if (this._reconnect) {
- this.reconnect();
- }
-};
+ if (hadError) {
+ self.emit('close', hadError, arguments[1]);
+ } else {
+ self.emit('close');
+ }
-//
-// ### @private function _onError (error)
-// #### @error {Error} emits and error event in place of the socket
-// Error event is raise with an error if there was one
-//
-NsSocket.prototype._onError = function _onError(error) {
- this.connected = false;
-
- if (!this._reconnect) {
- return this.emit('error', error || new Error('An Unknown Error occured'));
- }
-
- this.reconnect();
-};
+ self.retry && self.reconnect();
+ });
-//
-// ### @private function _onIdle ()
-// #### Emits the idle event (based on timeout)
-//
-NsSocket.prototype._onIdle = function _onIdle() {
- this.emit('idle');
- if (this._timeout) {
- this.socket.setTimeout(this._timeout);
- }
-};
+ self.socket.on('error', function (err) {
+ !self.retry && self.emit('error', err || new Error('An Unknown Error occured'));
+ });
+ self.socket.on('timeout', function onIdle() {
+ self.emit('idle');
+ self.timeout && self.socket.setTimeout(this.timeout);
+ });
+}
View
10 package.json
@@ -16,14 +16,14 @@
"eventemitter2": "0.4.x"
},
"devDependencies": {
- "vows": "0.6.x"
+ "mocha": "1.3.x",
+ "chai": "1.0.x"
},
- "main": "./lib/nssocket",
+ "main": "./",
"engines": {
"node": ">= 0.7.x"
},
"scripts": {
- "test": "vows test/*-test.js --spec"
+ "test": "make test"
}
-}
-
+}
View
57 test/buffer-tcp.test.js
@@ -0,0 +1,57 @@
+var net = require('net'),
+ fs = require ('fs'),
+ expect = require('chai').expect,
+ nssocket = require('../');
+
+var trollface = fs.readFileSync('test/fixtures/trollface.jpg');
+var TCP_PORT = 5467;
+
+describe('nssocket/tcp/buffer', function () {
+ before(function (done) {
+ var self = this;
+ this.server = net.createServer(function (inbound) {
+ self.inbound = inbound;
+ done();
+ });
+ this.server.listen(TCP_PORT, function () {
+ self.outbound = nssocket({ delimiter: '/' }).connect(TCP_PORT);
+ });
+ });
+ after(function () {
+ this.server.close();
+ this.outbound.end();
+ this.inbound.end();
+ });
+ describe('#send()', function () {
+ it('should correctly receive multi messages chunks / json', testMulti(5, { foo: 'bar' }));
+ it('should correctly receive multi messages chunks / buffer', testMulti(5, Buffer('foo:bar')));
+ it('should correctly receive multi messages chunks / large buffer', testMulti(5, trollface));
+ });
+});
+
+function testMulti(n, data) {
+ return function (done) {
+ var self = this;
+ var message = this.outbound.createMessage('test/multi', data);
+ var buffer = Buffer.concat(arrayOf(message, n), message.length * n);
+
+ function onMessage(data) {
+ n --;
+ expect(data).to.be.eql(data);
+ if (!n) {
+ self.outbound.off('data/test/multi', onMessage);
+ done();
+ }
+ }
+ this.outbound.on('data/test/multi', onMessage);
+ this.inbound.write(buffer);
+ };
+}
+
+function arrayOf(what, howmany) {
+ var arr = [];
+ for (var i = 0; i < howmany; i++) {
+ arr.push(what);
+ }
+ return arr;
+}
View
61 test/buffer-tls.test.js
@@ -0,0 +1,61 @@
+var tls = require('tls'),
+ fs = require ('fs'),
+ expect = require('chai').expect,
+ nssocket = require('../');
+
+var trollface = fs.readFileSync('test/fixtures/trollface.jpg');
+var TCP_PORT = 5467;
+
+describe('nssocket/tls/buffer', function () {
+ before(function (done) {
+ var self = this;
+ this.server = tls.createServer({
+ key: fs.readFileSync('test/fixtures/ryans-key.pem'),
+ cert: fs.readFileSync('test/fixtures/ryans-cert.pem'),
+ ca: fs.readFileSync('test/fixtures/ryans-csr.pem')
+ }, function (inbound) {
+ self.inbound = inbound;
+ done();
+ });
+ this.server.listen(TCP_PORT, function () {
+ self.outbound = nssocket({ type : 'tls', delimiter: '/' }).connect(TCP_PORT);
+ });
+ });
+ after(function () {
+ this.server.close();
+ this.inbound.end();
+ this.outbound.end();
+ });
+ describe('#send()', function () {
+ it('should correctly receive multi messages chunks / json', testMulti(5, { foo: 'bar' }));
+ it('should correctly receive multi messages chunks / buffer', testMulti(5, Buffer('foo:bar')));
+ it('should correctly receive multi messages chunks / large buffer', testMulti(5, trollface));
+ });
+});
+
+function testMulti(n, data) {
+ return function (done) {
+ var self = this;
+ var message = this.outbound.createMessage('test/multi', data);
+ var buffer = Buffer.concat(arrayOf(message, n), message.length * n);
+
+ function onMessage(data) {
+ n --;
+ expect(data).to.be.eql(data);
+ if (!n) {
+ self.outbound.off('data/test/multi', onMessage);
+ done();
+ }
+ }
+ this.outbound.on('data/test/multi', onMessage);
+ this.inbound.write(buffer);
+ };
+}
+
+function arrayOf(what, howmany) {
+ var arr = [];
+ for (var i = 0; i < howmany; i++) {
+ arr.push(what);
+ }
+ return arr;
+}
View
72 test/create-server-test.js
@@ -1,72 +0,0 @@
-/*
- * create-server-test.js : namespace socket unit test for TLS.
- *
- * (C) 2011, Nodejitsu Inc.
- *
- */
-
-var assert = require('assert'),
- fs = require('fs'),
- net = require('net'),
- path = require('path'),
- tls = require('tls'),
- vows = require('vows'),
- nssocket = require('../lib/nssocket');
-
-
-function getBatch() {
- var args = Array.prototype.slice.call(arguments),
- res = {};
-
- return {
- "the createServer() method": {
- topic: function () {
- var outbound = new nssocket.NsSocket(),
- server = nssocket.createServer(this.callback.bind(null, null, outbound));
-
- server.listen.apply(server, args.concat(function () {
- outbound.connect.apply(outbound, args);
- }));
- },
- "should create a full-duplex namespaced socket": {
- topic: function (outbound, inbound) {
- outbound.on(['data', 'here', 'is'], this.callback.bind(outbound, null));
- inbound.send(['here', 'is'], 'something.');
- },
- "should handle namespaced events": function (_, data) {
- assert.isArray(this.event);
- assert.lengthOf(this.event, 3);
- assert.isString(this.event[0]);
- assert.isString(this.event[1]);
- assert.isString(this.event[2]);
- assert.isString(data);
- assert.equal(this.event[0], 'data');
- assert.equal(this.event[1], 'here');
- assert.equal(this.event[2], 'is');
- assert.equal(data, 'something.');
- }
- }
- }
- };
-}
-
-var PORT = 9564,
- HOST = "127.0.0.1",
- PIPE = path.join(__dirname, "fixtures", "nssocket.sock"),
- HOSTNAME = "localhost";
-
-vows.describe('nssocket/create-server').addBatch({
- "When using NsSocket": {
- "with `(PORT)` argument": getBatch(PORT),
- "with `(PORT, HOST)` arguments": getBatch(PORT + 1, HOST),
- "with `(PORT, HOSTNAME)` argument": getBatch(PORT + 2, HOSTNAME),
- "with `(PIPE)` argument": getBatch(PIPE)
- }
-}).addBatch({
- "When tests are finished": {
- "`PIPE` should be removed": function () {
- fs.unlinkSync(PIPE);
- }
- }
-}).export(module);
-
View
57 test/create-server.test.js
@@ -0,0 +1,57 @@
+/*
+ * create-server-test.js : namespace socket unit test for TLS.
+ *
+ * (C) 2011, Nodejitsu Inc.
+ *
+ */
+
+var net = require('net'),
+ tls = require('tls'),
+ fs = require ('fs'),
+ path = require('path'),
+ assert = require('chai').assert,
+ nssocket = require('../');
+
+var PORT = 9568;
+var HOST = '127.0.0.1';
+var HOSTNAME = 'localhost';
+var PIPE = path.join(__dirname, 'fixtures', 'nssocket.sock');
+
+describe('nssocket/create-server', function () {
+ describe('#listen()', function () {
+ before(function() {
+ try { fs.unlinkSync(FD); }
+ catch (err) {}
+ });
+ afterEach(function (done) {
+ this.server.close(done);
+ this.outbound.end();
+ this.inbound.end();
+ });
+ it('should create a full-duplex namespaced socket / (PORT)', testWith(PORT));
+ it('should create a full-duplex namespaced socket / (PORT, HOST)', testWith(PORT, HOST));
+ it('should create a full-duplex namespaced socket / (PORT, HOSTNAME)', testWith(PORT, HOSTNAME));
+ it('should create a full-duplex namespaced socket / (PIPE)', testWith(PIPE));
+ });
+});
+
+function testWith() {
+ var args = [].slice.call(arguments);
+
+ return function (done) {
+ var self = this;
+ self.server = nssocket.createServer(function (inbound) {
+ self.inbound = inbound;
+ self.outbound.on(['data', 'here', 'is'], function (data) {
+ assert.deepEqual(this.event, ['data', 'here', 'is']);
+ assert.equal(data, 'something.');
+ done();
+ });
+ self.inbound.send(['here', 'is'], 'something.');
+ });
+ self.server.listen.apply(self.server, args.concat(function () {
+ self.outbound = nssocket();
+ self.outbound.connect.apply(self.outbound, args);
+ }));
+ };
+}
View
BIN  test/fixtures/trollface.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
80 test/tcp-reconnect-test.js
@@ -1,80 +0,0 @@
-/*
- * nssocket-test.js : namespace socket unit test for TCP
- *
- * (C) 2011, Nodejitsu Inc.
- *
- */
-
-var assert = require('assert'),
- fs = require('fs'),
- net = require('net'),
- path = require('path'),
- vows = require('vows'),
- NsSocket = require('../lib/nssocket').NsSocket;
-
-var TCP_PORT = 30105;
-
-var tcpServer = net.createServer(),
- tcpOpt;
-
-tcpOpt = {
- type : 'tcp4',
- delimiter: '.}',
- reconnect: true,
- retryInterval: 1000
-};
-
-tcpServer.listen(TCP_PORT);
-
-vows.describe('nssocket/tcp/reconnect').addBatch({
- "When using NsSocket with TCP": {
- topic: new NsSocket(tcpOpt),
- "the connect() method": {
- topic: function (outbound) {
- var that = this;
- tcpServer.on('connection', this.callback.bind(null, null, outbound));
- outbound.connect(TCP_PORT);
- },
- "should actually connect": function (_, outbound, inbound) {
- assert.instanceOf(outbound, NsSocket);
- assert.instanceOf(inbound, net.Socket);
- },
- "when the server closes": {
- topic: function (outbound, inbound) {
- outbound.once('close', this.callback.bind(this, null, outbound));
- tcpServer.close();
- inbound.destroy();
- },
- "and then restarts": {
- topic: function (outbound) {
- tcpServer = net.createServer();
- tcpServer.listen(TCP_PORT);
- tcpServer.on('connection', this.callback.bind(null, null, outbound));
- },
- "the socket should reconnect correctly": function (_, outbound, inbound) {
- assert.instanceOf(outbound, NsSocket);
- assert.instanceOf(inbound, net.Socket);
- },
- "the on() method": {
- topic: function (outbound, inbound) {
- outbound.on('data.}here.}is', this.callback.bind(outbound, null));
- inbound.write(Buffer('0000000d0000000c005b2268657265222c226973225d22736f6d657468696e672e22', 'hex'));
- },
- "should handle namespaced events": function (_, data) {
- assert.isArray(this.event);
- assert.lengthOf(this.event, 3);
- assert.isString(this.event[0]);
- assert.isString(this.event[1]);
- assert.isString(this.event[2]);
- assert.isString(data);
- assert.equal(this.event[0], 'data');
- assert.equal(this.event[1], 'here');
- assert.equal(this.event[2], 'is');
- assert.equal(data, 'something.');
- }
- }
- }
- }
- }
- }
-}).export(module);
View
57 test/tcp-reconnect.test.js
@@ -0,0 +1,57 @@
+/*
+ * create-server-test.js : namespace socket unit test for TLS.
+ *
+ * (C) 2011, Nodejitsu Inc.
+ *
+ */
+
+var net = require('net'),
+ tls = require('tls'),
+ fs = require ('fs'),
+ path = require('path'),
+ assert = require('chai').assert,
+ nssocket = require('../');
+
+var TCP_PORT = 30105;
+var TCP_OPTIONS = {
+ type : 'tcp4',
+ delimiter: '.}',
+ reconnect: true,
+ retryInterval: 200
+};
+
+describe('nssocket/tcp/reconnect', function () {
+ after(function (done) {
+ this.server.close(done);
+ this.outbound.end();
+ this.inbound.end();
+ });
+ describe('client', function () {
+ it('should connect', function (done) {
+ var self = this;
+ self.outbound = nssocket(TCP_OPTIONS).connect(TCP_PORT);
+ self.server = nssocket.createServer(TCP_OPTIONS, done.bind(null, null));
+ setTimeout(function () {
+ self.server.listen(TCP_PORT);
+ }, 200);
+ });
+ it('should handle reconnection', function (done) {
+ var self = this;
+ self.server.close(function () {
+ self.server = nssocket.createServer(TCP_OPTIONS, function (inbound) {
+ self.inbound = inbound;
+ done();
+ }).listen(TCP_PORT);
+ });
+ self.outbound.end();
+ });
+ it('should be able to send after reconnection', function (done) {
+ this.outbound.once('data.}here.}is', function (data) {
+ assert.deepEqual(this.event, ['data', 'here', 'is']);
+ assert.equal(data, 'something.');
+ done();
+ });
+ this.inbound.send('here.}is', 'something.');
+ });
+ });
+});
View
100 test/tcp-test.js
@@ -1,100 +0,0 @@
-/*
- * nssocket-test.js : namespace socket unit test for TCP
- *
- * (C) 2011, Nodejitsu Inc.
- *
- */
-
-var assert = require('assert'),
- fs = require('fs'),
- net = require('net'),
- path = require('path'),
- vows = require('vows'),
- NsSocket = require('../lib/nssocket').NsSocket;
-
-var TCP_PORT = 30103;
-
-var tcpServer = net.createServer(),
- tcpOpt;
-
-tcpOpt = {
- type : 'tcp4',
- delimiter: '.}'
-};
-
-tcpServer.listen(TCP_PORT);
-
-vows.describe('nssocket/tcp').addBatch({
- "When using NsSocket with TCP": {
- topic: new NsSocket(tcpOpt),
- "should create a wrapped socket": function (outbound) {
- assert.instanceOf(outbound, NsSocket);
- },
- "should have the proper configuration settings": function (outbound) {
- assert.equal(outbound._type, tcpOpt.type);
- assert.equal(outbound._delimiter, tcpOpt.delimiter);
- },
- "the connect() method": {
- topic: function (outbound) {
- var that = this;
- tcpServer.on('connection', this.callback.bind(null, null, outbound));
- outbound.connect(TCP_PORT);
- },
- "should actually connect": function (_, outbound, inbound) {
- assert.instanceOf(outbound, NsSocket);
- assert.instanceOf(inbound, net.Socket);
- },
- "the on() method": {
- topic: function (outbound, inbound) {
- outbound.on('data.}here.}is', this.callback.bind(outbound, null));
- inbound.write(Buffer('0000000d0000000c005b2268657265222c226973225d22736f6d657468696e672e22', 'hex'));
- },
- "should handle namespaced events": function (_, data) {
- assert.isArray(this.event);
- assert.lengthOf(this.event, 3);
- assert.isString(this.event[0]);
- assert.isString(this.event[1]);
- assert.isString(this.event[2]);
- assert.isString(data);
- assert.equal(this.event[0], 'data');
- assert.equal(this.event[1], 'here');
- assert.equal(this.event[2], 'is');
- assert.equal(data, 'something.');
- },
- "once idle": {
- topic: function (_, outbound, inbound) {
- outbound.once('idle', this.callback.bind(null, null, outbound, inbound));
- outbound.setIdle(100);
- },
- "it should emit `idle`": function (_, outbound, inbound) {
- assert.isNull(_);
- },
- "the send() method": {
- topic: function (outbound, inbound) {
- inbound.on('data', this.callback.bind(null, null, outbound, inbound));
- outbound.send(['hello','world'], Buffer('foo::bar'));
- },
- "we should see it on the other end": function (_, outbound, wraped, data) {
- assert.isObject(data);
- event = JSON.parse(data.slice(9, 26).toString());
- data = data.slice(26).toString();
- assert.lengthOf(event, 2);
- assert.equal(event[0], 'hello');
- assert.equal(event[1], 'world');
- assert.deepEqual(data, 'foo::bar');
- },
- "the end() method": {
- topic: function (outbound, inbound) {
- outbound.on('close', this.callback.bind(null, null, outbound, inbound));
- inbound.end();
- },
- "should close without errors": function (_, _, _, err) {
- assert.isUndefined(err);
- }
- }
- }
- }
- }
- }
- }
-}).export(module);
View
117 test/tcp.test.js
@@ -0,0 +1,117 @@
+/*
+ * create-server-test.js : namespace socket unit test for TLS.
+ *
+ * (C) 2011, Nodejitsu Inc.
+ *
+ */
+
+var net = require('net'),
+ tls = require('tls'),
+ fs = require ('fs'),
+ path = require('path'),
+ assert = require('chai').assert,
+ nssocket = require('../');
+
+var TCP_PORT = 30105;
+var TCP_OPTIONS = {
+ type : 'tcp4',
+ delimiter: '.}',
+ reconnect: true,
+ retryInterval: 200
+};
+
+describe('nssocket/tcp', function () {
+ after(function (done) {