Skip to content

Commit b96e2a0

Browse files
committed
net: persist net.Socket options before connect
Remembers net.Socket options called before connect and retroactively applies them after the handle has been created. This change makes the following function calls more user-friendly: - setKeepAlive() - setNoDelay() - ref() - unref() Related: nodejs/node-v0.x-archive#7077 and nodejs/node-v0.x-archive#8572
1 parent 813a536 commit b96e2a0

4 files changed

+126
-4
lines changed

lib/net.js

+22-4
Original file line numberDiff line numberDiff line change
@@ -328,13 +328,23 @@ Socket.prototype._onTimeout = function() {
328328

329329

330330
Socket.prototype.setNoDelay = function(enable) {
331+
if (!this._handle) {
332+
this.once('connect', this.setNoDelay.bind(this, enable));
333+
return;
334+
}
335+
331336
// backwards compatibility: assume true when `enable` is omitted
332337
if (this._handle && this._handle.setNoDelay)
333338
this._handle.setNoDelay(enable === undefined ? true : !!enable);
334339
};
335340

336341

337342
Socket.prototype.setKeepAlive = function(setting, msecs) {
343+
if (!this._handle) {
344+
this.once('connect', this.setKeepAlive.bind(this, setting, msecs));
345+
return;
346+
}
347+
338348
if (this._handle && this._handle.setKeepAlive)
339349
this._handle.setKeepAlive(setting, ~~(msecs / 1000));
340350
};
@@ -957,14 +967,22 @@ Socket.prototype.connect = function(options, cb) {
957967

958968

959969
Socket.prototype.ref = function() {
960-
if (this._handle)
961-
this._handle.ref();
970+
if (!this._handle) {
971+
this.once('connect', this.ref);
972+
return;
973+
}
974+
975+
this._handle.ref();
962976
};
963977

964978

965979
Socket.prototype.unref = function() {
966-
if (this._handle)
967-
this._handle.unref();
980+
if (!this._handle) {
981+
this.once('connect', this.unref);
982+
return;
983+
}
984+
985+
this._handle.unref();
968986
};
969987

970988

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
var common = require('../common');
2+
var assert = require('assert');
3+
var net = require('net');
4+
5+
var serverConnection;
6+
var echoServer = net.createServer(function(connection) {
7+
serverConnection = connection;
8+
connection.setTimeout(0);
9+
assert.notEqual(connection.setKeepAlive, undefined);
10+
connection.on('end', function() {
11+
connection.end();
12+
});
13+
});
14+
echoServer.listen(common.PORT);
15+
16+
echoServer.on('listening', function() {
17+
var clientConnection = new net.Socket();
18+
// send a keepalive packet after 1000 ms
19+
// and make sure it persists
20+
clientConnection.setKeepAlive(true, 400);
21+
clientConnection.connect(common.PORT);
22+
clientConnection.setTimeout(0);
23+
24+
setTimeout(function() {
25+
// make sure both connections are still open
26+
assert.equal(serverConnection.readyState, 'open');
27+
assert.equal(clientConnection.readyState, 'open');
28+
serverConnection.end();
29+
clientConnection.end();
30+
echoServer.close();
31+
}, 600);
32+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
var common = require('../common');
2+
var assert = require('assert');
3+
var net = require('net');
4+
var TCPWrap = process.binding('tcp_wrap').TCP;
5+
6+
var echoServer = net.createServer(function(connection) {
7+
connection.end();
8+
});
9+
echoServer.listen(common.PORT);
10+
11+
var setTrue = 0;
12+
13+
var Socket = net.Socket;
14+
var setNoDelay = TCPWrap.prototype.setNoDelay;
15+
16+
TCPWrap.prototype.setNoDelay = function(enable) {
17+
setNoDelay.call(this, enable);
18+
setTrue++;
19+
};
20+
21+
echoServer.on('listening', function() {
22+
var sock1 = new Socket();
23+
// setNoDelay before the handle is created
24+
// there is probably a better way to test this
25+
26+
sock1.setNoDelay();
27+
sock1.connect(common.PORT);
28+
sock1.on('end', process.exit);
29+
});
30+
31+
process.on('exit', function() {
32+
assert.ok(setTrue);
33+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
var common = require('../common');
2+
var assert = require('assert');
3+
var net = require('net');
4+
var TCPWrap = process.binding('tcp_wrap').TCP;
5+
6+
var echoServer = net.createServer(function(conn) {
7+
conn.end();
8+
});
9+
10+
var ref = TCPWrap.prototype.ref;
11+
var unref = TCPWrap.prototype.unref;
12+
13+
var refed = false;
14+
var unrefed = false;
15+
16+
TCPWrap.prototype.ref = function() {
17+
ref.call(this);
18+
refed = true;
19+
};
20+
21+
TCPWrap.prototype.unref = function() {
22+
unref.call(this);
23+
unrefed = true;
24+
};
25+
26+
echoServer.listen(common.PORT);
27+
28+
echoServer.on('listening', function() {
29+
var sock = new net.Socket();
30+
sock.unref();
31+
sock.ref();
32+
sock.connect(common.PORT);
33+
sock.on('end', process.exit);
34+
});
35+
36+
process.on('exit', function() {
37+
assert.ok(refed);
38+
assert.ok(unrefed);
39+
});

0 commit comments

Comments
 (0)