diff --git a/lib/net.js b/lib/net.js index af8c3dd8feb68e..f7b80a3d18410f 100644 --- a/lib/net.js +++ b/lib/net.js @@ -121,6 +121,9 @@ function Socket(options) { this._hadError = false; this._handle = null; this._host = null; + this._unref = false; + this._setNoDelay = null; + this._setKeepAlive = null; if (typeof options === 'number') options = { fd: options }; // Legacy interface. @@ -323,12 +326,16 @@ Socket.prototype._onTimeout = function() { Socket.prototype.setNoDelay = function(enable) { // backwards compatibility: assume true when `enable` is omitted + this._setNoDelay = enable === undefined ? true : !!enable; + if (this._handle && this._handle.setNoDelay) - this._handle.setNoDelay(enable === undefined ? true : !!enable); + this._handle.setNoDelay(this._setNoDelay); }; Socket.prototype.setKeepAlive = function(setting, msecs) { + this._setKeepAlive = [setting, msecs]; + if (this._handle && this._handle.setKeepAlive) this._handle.setKeepAlive(setting, ~~(msecs / 1000)); }; @@ -766,6 +773,14 @@ function connect(self, address, port, addressType, localAddress, localPort) { var err; + self.setNoDelay(self._setNoDelay); + + if (self._setKeepAlive) + self.setKeepAlive(self._setKeepAlive[0], self._setKeepAlive[1]); + + if (self._unref) + self.unref(); + if (localAddress || localPort) { var bind; @@ -933,12 +948,16 @@ Socket.prototype.connect = function(options, cb) { Socket.prototype.ref = function() { + this._unref = false; + if (this._handle) this._handle.ref(); }; Socket.prototype.unref = function() { + this._unref = true; + if (this._handle) this._handle.unref(); }; diff --git a/test/parallel/test-net-persistent-keepalive.js b/test/parallel/test-net-persistent-keepalive.js new file mode 100644 index 00000000000000..e26664e3db8000 --- /dev/null +++ b/test/parallel/test-net-persistent-keepalive.js @@ -0,0 +1,34 @@ +var common = require('../common'); +var assert = require('assert'); +var net = require('net'); + +var serverConnection; +var echoServer = net.createServer(function(connection) { + serverConnection = connection; + connection.setTimeout(0); + assert.notEqual(connection.setKeepAlive, undefined); + connection.on('end', function() { + connection.end(); + }); +}); +echoServer.listen(common.PORT); + +echoServer.on('listening', function() { + var clientConnection = new net.Socket({}); + // send a keepalive packet after 1000 ms + // and make sure it persists + clientConnection.setKeepAlive(true, 1000); + clientConnection.connect(common.PORT); + clientConnection.setTimeout(0); + assert.equal(clientConnection._setKeepAlive[0], true); + assert.equal(clientConnection._setKeepAlive[1], 1000); + + setTimeout(function() { + // make sure both connections are still open + assert.equal(serverConnection.readyState, 'open'); + assert.equal(clientConnection.readyState, 'open'); + serverConnection.end(); + clientConnection.end(); + echoServer.close(); + }, 1200); +}); diff --git a/test/parallel/test-net-persistent-nodelay.js b/test/parallel/test-net-persistent-nodelay.js new file mode 100644 index 00000000000000..24994f430df612 --- /dev/null +++ b/test/parallel/test-net-persistent-nodelay.js @@ -0,0 +1,43 @@ +var common = require('../common'); +var assert = require('assert'); +var net = require('net'); + +var serverConnection; +var echoServer = net.createServer(function(connection) { + serverConnection = connection; + connection.end() +}); +echoServer.listen(common.PORT); + +var setTrue = false; + +var Socket = net.Socket; + +Socket.prototype.setNoDelay = function(enable) { + this._setNoDelay = enable === undefined ? true : !!enable; + if (this._handle && this._handle.setNoDelay) { + if (enable === undefined || !!enable) { + setTrue = true; + } + this._handle.setNoDelay(this._setNoDelay); + } +} + +echoServer.on('listening', function() { + var sock1 = new Socket({}); + // setNoDelay before the handle is created + // there is probably a better way to test this + + sock1.setNoDelay(); + assert.equal(sock1._setNoDelay, true); + sock1.connect(common.PORT, function() { + var sock2 = new Socket({}); + assert.equal(sock2._setNoDelay, null); + sock2.connect(common.PORT, function() { + assert.ok(setTrue); + setTimeout(function() { + echoServer.close(); + }, 500); + }); + }); +});