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
|
||||
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
|
||||
|
||||
|
11
lib/net.js
11
lib/net.js
@ -38,6 +38,7 @@ var read = binding.read;
|
||||
var write = binding.write;
|
||||
var toRead = binding.toRead;
|
||||
var setNoDelay = binding.setNoDelay;
|
||||
var setKeepAlive= binding.setKeepAlive;
|
||||
var socketError = binding.socketError;
|
||||
var getsockname = binding.getsockname;
|
||||
var errnoException = binding.errnoException;
|
||||
@ -744,9 +745,17 @@ Stream.prototype.address = function () {
|
||||
|
||||
|
||||
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) {
|
||||
timeout.enroll(this, msecs);
|
||||
|
@ -1062,11 +1062,43 @@ static Handle<Value> SetNoDelay(const Arguments& args) {
|
||||
if (r < 0) {
|
||||
return ThrowException(ErrnoException(errno, "setsockopt"));
|
||||
}
|
||||
|
||||
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
|
||||
//
|
||||
@ -1287,6 +1319,7 @@ void InitNet2(Handle<Object> target) {
|
||||
NODE_SET_METHOD(target, "socketError", SocketError);
|
||||
NODE_SET_METHOD(target, "toRead", ToRead);
|
||||
NODE_SET_METHOD(target, "setNoDelay", SetNoDelay);
|
||||
NODE_SET_METHOD(target, "setKeepAlive", SetKeepAlive);
|
||||
NODE_SET_METHOD(target, "getsockname", GetSockName);
|
||||
NODE_SET_METHOD(target, "getpeername", GetPeerName);
|
||||
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