2013-09-04 91 views
5

Quoted from TCP keepalive HowTo:Tại sao NodeJS KeepAlive dường như không hoạt động như mong đợi?

In order to understand what TCP keepalive (which we will just call keepalive) does, you need do nothing more than read the name: keep TCP alive. This means that you will be able to check your connected socket (also known as TCP sockets), and determine whether the connection is still up and running or if it has broken.

Vậy tại sao là mã sau không ném một cái gì đó khi kết nối Internet bị hỏng?

var tls = require('tls'); 

var socket = tls.connect(443, "google.com", function connected() { 
    console.log('connected'); 
}); 

socket.setNoDelay(true); 
socket.setKeepAlive(true, 0); 
socket.setTimeout(0, function(){ 
    console.log('timeout'); 
}); 
socket.on('data', function(data) { 
    console.log(data); 
}); 
socket.on('close', function() { 
    console.error("close"); 
}); 
socket.on('error', function(err) { 
    console.error("error", err); 
}); 

Thử nghiệm trên hệ điều hành MacOS/Debian, với NodeJS v0.10.17

Trả lời

6

Trích dẫn man 7 tcp:

tcp_keepalive_time (integer; default: 7200; since Linux 2.2)

The number of seconds a connection needs to be idle before TCP begins sending out keep-alive probes. Keep-alives are only sent when the SO_KEEPALIVE socket option is enabled. The default value is 7200 seconds (2 hours). An idle connection is terminated after approximately an additional 11 minutes (9 probes an interval of 75 seconds apart) when keep-alive is enabled.

Vì vậy, sau ~ 10 phút (trên hệ điều hành MacOS 10.8) nút phát ra một lỗi:

error { [Error: read ETIMEDOUT] code: 'ETIMEDOUT', errno: 'ETIMEDOUT', syscall: 'read' } 
1

https://www.npmjs.com/package/net-keepalive

Đây là mô-đun cho phép bạn định cấu hình TCP_KEEPINTVL và TCP_KEEPCNT trên mỗi socket.

Provides high-level access to socket options like TCP_KEEPIDLE, TCP_KEEPINTVL, TCP_KEEPCNT

var Net = require('net') 
    , NetKeepAlive = require('net-keepalive') 
; 

// Create a TCP Server 
var srv = Net.createServer(function(s){> 
    console.log('Connected %j', s.address()) 
    // Doesn't matter what it does 
    s.pipe(s) 
}); 

// Start on some port 
srv.listen(1337, function(){ 
    console.log('Listening on %j', srv.address()) 
}); 

// Connect to that server 
var s = Net.createConnection({port:1337}, function(){ 
    console.log('Connected to %j', s.address()) 

    //IMPORTANT: KeepAlive must be enabled for this to work 
    s.setKeepAlive(true, 1000) 

    // Set TCP_KEEPINTVL for this specific socket 
    NetKeepAlive.setKeepAliveInterval(s, 1000) 

    // and TCP_KEEPCNT 
    NetKeepAlive.setKeepAliveProbes(s, 1) 
});