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

背景

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

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

问题

问题是,如果我手动断开networking电缆从机器上,我的Node.js连接不会触发close事件,我无法知道是否失败!

 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(); 

研究

@robertklep提到了setKeepAlive选项,但根据

如何在NodeJS中testingsocket.setKeepAlive

它不工作。 更深入的研究表明,这是高度依赖于您正在使用的操作系统,按照https://stackoverflow.com/a/18678494/1337392

换句话说,除非我愿意等几分钟才能真正做点什么,否则我看不出有什么办法。

如何检测连接是否死亡?

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

特别要注意这句话:

需要注意的是,接收数据的行为在TCP中是完全被动的; 只有读取的套接字才能检测到丢失的连接。

这正是你的情况发生了什么:你的套接字正在等待新的数据到达,这从来没有发生。 某些操作系统,尤其是UNIXtypes的操作系统,如果networking接口故障,可能会等待很长时间才会使开放式连接失效。

本文还提出了一个可以在Node.js上工作的解决scheme:启用TCP Keepalive。 这将周期性地发送数据包到对端来检查连接是否仍在工作。

要在你的套接字上启用这个function,

 socket.setKeepalive(true, 5000); 

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