add setKeepAlive function, which enables and sets the TCP keep-alive timer
This commit is contained in:
parent
27ec33aad7
commit
5f8f561d61
@ -2042,6 +2042,15 @@ Disables the Nagle algorithm. By default TCP connections use the Nagle
|
|||||||
algorithm, they buffer data before sending it off. Setting `noDelay` will
|
algorithm, they buffer data before sending it off. Setting `noDelay` will
|
||||||
immediately fire off data each time `stream.write()` is called.
|
immediately fire off data each time `stream.write()` is called.
|
||||||
|
|
||||||
|
### stream.setKeepAlive(enable=false, initialDelay)
|
||||||
|
|
||||||
|
Enable/disable keep-alive functionality, and optionally set the initial
|
||||||
|
delay before the first keepalive probe is sent on an idle stream.
|
||||||
|
Set `initialDelay` (in milliseconds) to set the delay between the last
|
||||||
|
data packet received and the first keepalive probe. Setting 0 for
|
||||||
|
initialDelay will leave the value unchanged from the default
|
||||||
|
(or previous) setting.
|
||||||
|
|
||||||
|
|
||||||
## DNS
|
## DNS
|
||||||
|
|
||||||
|
11
lib/net.js
11
lib/net.js
@ -38,6 +38,7 @@ var read = binding.read;
|
|||||||
var write = binding.write;
|
var write = binding.write;
|
||||||
var toRead = binding.toRead;
|
var toRead = binding.toRead;
|
||||||
var setNoDelay = binding.setNoDelay;
|
var setNoDelay = binding.setNoDelay;
|
||||||
|
var setKeepAlive= binding.setKeepAlive;
|
||||||
var socketError = binding.socketError;
|
var socketError = binding.socketError;
|
||||||
var getsockname = binding.getsockname;
|
var getsockname = binding.getsockname;
|
||||||
var errnoException = binding.errnoException;
|
var errnoException = binding.errnoException;
|
||||||
@ -744,9 +745,17 @@ Stream.prototype.address = function () {
|
|||||||
|
|
||||||
|
|
||||||
Stream.prototype.setNoDelay = function (v) {
|
Stream.prototype.setNoDelay = function (v) {
|
||||||
if (this.type == 'tcp') setNoDelay(this.fd, v);
|
if ((this.type == 'tcp4')||(this.type == 'tcp6')) {
|
||||||
|
setNoDelay(this.fd, v);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Stream.prototype.setKeepAlive = function (enable, time) {
|
||||||
|
if ((this.type == 'tcp4')||(this.type == 'tcp6')) {
|
||||||
|
var secondDelay = Math.ceil(time/1000);
|
||||||
|
setKeepAlive(this.fd, enable, secondDelay);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
Stream.prototype.setTimeout = function (msecs) {
|
Stream.prototype.setTimeout = function (msecs) {
|
||||||
timeout.enroll(this, msecs);
|
timeout.enroll(this, msecs);
|
||||||
|
@ -1062,11 +1062,43 @@ static Handle<Value> SetNoDelay(const Arguments& args) {
|
|||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
return ThrowException(ErrnoException(errno, "setsockopt"));
|
return ThrowException(ErrnoException(errno, "setsockopt"));
|
||||||
}
|
}
|
||||||
|
|
||||||
return Undefined();
|
return Undefined();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static Handle<Value> SetKeepAlive(const Arguments& args) {
|
||||||
|
int r;
|
||||||
|
HandleScope scope;
|
||||||
|
|
||||||
|
bool enable = false;
|
||||||
|
int time = 0;
|
||||||
|
|
||||||
|
FD_ARG(args[0])
|
||||||
|
|
||||||
|
if (args.Length() > 0) enable = args[1]->IsTrue();
|
||||||
|
if (enable == true) {
|
||||||
|
time = args[2]->Int32Value();
|
||||||
|
}
|
||||||
|
|
||||||
|
int flags = enable ? 1 : 0;
|
||||||
|
r = setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&flags, sizeof(flags));
|
||||||
|
if ((time > 0)&&(r >= 0)) {
|
||||||
|
#if defined(__APPLE__)
|
||||||
|
// Mac uses a different setting name than Linux
|
||||||
|
r = setsockopt(fd, IPPROTO_TCP, TCP_KEEPALIVE, (void *)&time, sizeof(time));
|
||||||
|
#elif defined(__sun)
|
||||||
|
// Solaris doesn't support TCP_KEEPIDLE, so do nothing here
|
||||||
|
#else
|
||||||
|
// assume anything else uses the Linux/BSD method
|
||||||
|
r = setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, (void *)&time, sizeof(time));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
if (r < 0) {
|
||||||
|
return ThrowException(ErrnoException(errno, "setsockopt"));
|
||||||
|
}
|
||||||
|
return Undefined();
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// G E T A D D R I N F O
|
// G E T A D D R I N F O
|
||||||
//
|
//
|
||||||
@ -1287,6 +1319,7 @@ void InitNet2(Handle<Object> target) {
|
|||||||
NODE_SET_METHOD(target, "socketError", SocketError);
|
NODE_SET_METHOD(target, "socketError", SocketError);
|
||||||
NODE_SET_METHOD(target, "toRead", ToRead);
|
NODE_SET_METHOD(target, "toRead", ToRead);
|
||||||
NODE_SET_METHOD(target, "setNoDelay", SetNoDelay);
|
NODE_SET_METHOD(target, "setNoDelay", SetNoDelay);
|
||||||
|
NODE_SET_METHOD(target, "setKeepAlive", SetKeepAlive);
|
||||||
NODE_SET_METHOD(target, "getsockname", GetSockName);
|
NODE_SET_METHOD(target, "getsockname", GetSockName);
|
||||||
NODE_SET_METHOD(target, "getpeername", GetPeerName);
|
NODE_SET_METHOD(target, "getpeername", GetPeerName);
|
||||||
NODE_SET_METHOD(target, "getaddrinfo", GetAddrInfo);
|
NODE_SET_METHOD(target, "getaddrinfo", GetAddrInfo);
|
||||||
|
28
test/simple/test-tcp-keepalive.js
Normal file
28
test/simple/test-tcp-keepalive.js
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
require("../common");
|
||||||
|
net = require('net');
|
||||||
|
|
||||||
|
var serverConnection;
|
||||||
|
var echoServer = net.createServer(function (connection) {
|
||||||
|
serverConnection = connection;
|
||||||
|
connection.setTimeout(0);
|
||||||
|
assert.notEqual(connection.setKeepAlive,undefined);
|
||||||
|
// send a keepalive packet after 1000 ms
|
||||||
|
connection.setKeepAlive(true,1000);
|
||||||
|
connection.addListener("end", function () {
|
||||||
|
connection.end();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
echoServer.listen(PORT);
|
||||||
|
|
||||||
|
var clientConnection = net.createConnection(PORT);
|
||||||
|
clientConnection.setTimeout(0);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user