如何检测net.Socket连接是否死亡 - node.js

时间:2017-05-30 11:52:16

标签: javascript node.js sockets tcp-ip

背景

我正在使用net.Socket通过TCP / IP与计算机进行通信。

我能够建立连接并发送和接收缓冲区数据包,这一切都很好。

问题

问题是如果我手动断开网络电缆与机器的连接,我的Node.js连接不会触发./manage.py migrate --fake 事件,我无法知道是否有故障!

代码

close

研究

@robertklep提到let socket; const start = async function ( config ) { await connecToBarrier( config ) .then( () => console.log( "connected to barrrier" ) ) .catch( err => { throw new Error( `Cannot connect to barrier: ${err}` ); } ); }; const connecToBarrier = function ( connectOpts ) { return new Promise( ( resolve, reject ) => { //connectOpts is an object with 'port' and 'host' socket = net.createConnection( connectOpts, () => { //once I receive a 'hello world' from the machine, I can continue socket.once( "data", () => resolve() ); } ); socket.on( "connection", () => { console.log("onConnection says we have someone!"); } ); socket.on( "error", err => { console.log(`onError says: ${err}`); reject(err); } ); socket.on( "timeout", () => { console.log("onTimeout says nothing"); reject(); } ); socket.on( "end", () => { console.log("onEnd says nothing"); reject(); } ); socket.on( "close", err => { console.log(`onClose says: ${err}`); reject(err); } ); } ); }; start(); 选项,但是根据

How to test socket.setKeepAlive in NodeJS

它没有用。更深入的研究表明,这很大程度上取决于您使用的操作系统,按照https://stackoverflow.com/a/18678494/1337392

换句话说,除非我愿意等待几分钟让我的心跳实际上做些什么,否则我也看不出任何方法。

问题

如何检测连接是否已死亡?

2 个答案:

答案 0 :(得分:4)

这是一个有趣的读物:https://blog.stephencleary.com/2009/05/detection-of-half-open-dropped.html

特别注意这句话:

  

值得注意的是,TCP中接收数据的行为完全是被动的;只读取的套接字无法检测到丢弃的连接。

这正是您所遇到的情况:您的套接字正在等待新数据到达,这种情况从未发生过。某些操作系统,特别是UNIX类型的操作系统,如果网络接口出现故障,可能会在开始无效的开放连接之前等待很长时间。

本文还提出了一个可以在Node.js上运行的解决方案:启用TCP Keepalive。这将定期向对等方发送数据包,以检查连接是否仍在工作。

要在套接字上启用此功能:

rsync

这将在收到最后一个数据包5秒后开始检查连接。更多信息:https://nodejs.org/api/net.html#net_socket_setkeepalive_enable_initialdelay

答案 1 :(得分:1)

同样的问题最终导致重新连接

const _connect = () =>{

  const socket  = new net.Socket();
    socket.connect(this.port, this.host);
    socket.setTimeout(10000);
    socket.on('timeout', () => {
        socket.destroy();
        _connect(); 
  });
  
}