javascript - 如何检测 net.Socket 连接是否终止 - node.js

标签 javascript node.js sockets tcp

背景

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

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

问题

问题是,如果我手动断开机器上的互联网电缆,我的 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 选项,但是根据

How to test socket.setKeepAlive in NodeJS

这是行不通的。根据 https://stackoverflow.com/a/18678494/1337392,一项更深入的研究表明,这在很大程度上取决于您使用的操作系统。

所以换句话说,除非我愿意等待几分钟让我的心跳真正做一些事情,否则我看不出有什么办法可以解决这个问题。

问题

如何检测连接是否断开?

最佳答案

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

请特别注意这句话:

It is important to note that the act of receiving data is completely passive in TCP; a socket that only reads cannot detect a dropped connection.

这正是您的情况:您的套接字正在等待新数据到达,但这种情况从未发生过。如果网络接口(interface)出现故障,某些操作系统,尤其是 UNIX 类型的操作系统,可能会等待很长时间才能开始使打开的连接失效。

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

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

socket.setKeepalive(true, 5000);

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

关于javascript - 如何检测 net.Socket 连接是否终止 - node.js,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44261512/

相关文章:

javascript - React componentWillUpdate 被调用两次

node.js - 错误 : Can't set headers after they are sent. - NodeJS 和 Express

node.js - 使用标准 gitflow 对 npm 依赖项进行版本控制

c++ - 设计面向对象的同步接收机和发射机

C - 带线程的套接字聊天服务器 - 昵称数组

javascript - 正则表达式匹配字符串中的数字但不匹配百分比

javascript - 将 JavaScript 转换为 C++

node.js - 使用 Node 转换来自 Azure 表存储的响应

java - 使用 Java 检查开放端口

javascript - 如何修复 linting no shadowed variable 警告