You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何正确使用net.connect与TCP Socket API交互 避免服务端崩溃

问题1:连接模式选择

优先选择保持长连接每秒发送一次请求,你当前的短连接逻辑就是触发服务端报错的核心原因:

  • 每次TCP连接的建立、断开都会占用服务端的端口、文件描述符资源,高频短连接会导致服务端堆积大量TIME_WAIT状态的残留连接,资源耗尽后就会拒绝新连接,也就是你遇到的ECONNREFUSED报错。
  • 每秒一次的请求频率很低,长连接几乎不会带来额外资源消耗,还能省去TCP三次握手、四次挥手的性能开销。

问题2:长连接实现方案

长连接需要实现连接生命周期管理、错误重连、TCP保活、粘包处理几个核心逻辑,完整实现代码如下:

const net = require('net');
let socketClient = null;
let running = true; // 轮询开关
const refreshRate = 1000; // 1秒请求间隔
// 提前定义请求体,避免每次重复生成
const request = '{"id":1,"jsonrpc":"2.0","method":"getdetails"}\r\n';

// 初始化/重连TCP连接
function initConnection() {
    // 销毁旧连接避免资源泄漏
    if (socketClient) {
        socketClient.removeAllListeners();
        socketClient.destroy();
        socketClient = null;
    }

    socketClient = net.connect({host:'localhost', port:8888}, () => {
        console.log('API连接建立成功');
        // 开启TCP keep-alive:空闲30秒后开始发送探测包,检测连接是否存活
        socketClient.setKeepAlive(true, 30 * 1000);
        // 禁用Nagle算法,降低小包发送延迟,适配你的高频小包请求场景
        socketClient.setNoDelay(true);
    });

    // 处理响应数据(含粘包处理,TCP是流协议无数据边界,不能假设单次data事件返回完整JSON)
    let buffer = '';
    socketClient.on('data', (data) => {
        buffer += data.toString();
        // 按你约定的\r\n作为响应分隔符拆分完整数据包
        while (buffer.includes('\r\n')) {
            const [jsonStr, rest] = buffer.split('\r\n', 2);
            buffer = rest;
            try {
                const res = JSON.parse(jsonStr);
                if (res.result) updateUI(res.result);
            } catch (e) {
                console.error('响应解析失败', e);
            }
        }
    });

    // 连接错误自动重连
    socketClient.on('error', (err) => {
        console.error('连接异常', err);
        // 延迟2秒重连,避免频繁请求加重服务端负担
        setTimeout(initConnection, 2000);
    });

    // 连接断开自动重连
    socketClient.on('end', () => {
        console.log('API连接断开,尝试重连');
        setTimeout(initConnection, 2000);
    });
}

// 定时发送请求
function startPolling() {
    if (!running) return;
    setTimeout(() => {
        // 仅在连接可写时发送请求
        if (socketClient && socketClient.writable) {
            socketClient.write(request);
        }
        startPolling();
    }, refreshRate);
}

// 启动逻辑
initConnection();
startPolling();

// 需要停止轮询时调用
// function stopPolling() {
//     running = false;
//     if (socketClient) socketClient.destroy();
// }

注意事项

  • keep-alive配置必须开启,作用是检测连接假死,避免服务端已经断开但客户端仍认为连接正常的情况,上述代码已完成相关配置。
  • 粘包处理是TCP通信的必备逻辑,不能省略,否则会大概率出现JSON解析失败的问题。

内容的提问来源于stack exchange,提问作者Kyle Dixon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 08:21:02