首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Node.js 部署 WebSocket 服务:长连接频繁 1006 异常断开排查记录

Node.js 部署 WebSocket 服务:长连接频繁 1006 异常断开排查记录

原创
作者头像
1024_officlal
发布于 2026-11-07 10:34:01
发布于 2026-11-07 10:34:01
1390
举报

最近在开发一个基于 Node.js 的实时数据看板应用。本地开发时,前端的 WebSocket 与后端的连接稳如泰山,但把后端服务部署到腾讯云服务器,并连接海外的第三方实时数据源(如 Supabase Realtime 或海外自建网关)后,频繁遇到连接断开的问题。

前端控制台时常报 WebSocket connection to 'wss://...' failed: Error 1006,随后触发重连,没多久又断。排查了 Nginx 的 proxy_read_timeout 和 Node.js 的 Keep-Alive 设置,依然无济于事。本文记录这次排查过程与底层网络原理。

一、现象与初步排查

1. Nginx 反向代理配置排查 起初怀疑是 Nginx 掐断了连接,调整了超时时间,但问题依旧:

代码语言:javascript
复制
location /ws/ {
    proxy_pass http://localhost:3000;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "Upgrade";
    proxy_read_timeout 3600s; # 已经拉到 1 小时
}

2. 抓包分析 在服务器上通过 tcpdump 抓包,发现连接并不是本地服务端发起的断开,而是客户端(或者说中间层)发起了 RST 包。而且,每次发生断连的时间极不规律,有时候几分钟,有时候十几分钟。

3. 检查出口 IP 属性 登录服务器,查看公网出口 IP 属性:

代码语言:javascript
复制
curl -s https://ipinfo.io/json | jq '.org, .asn'

结果显示当前服务器的 IP 属于某云服务商(Tencent Cloud)的数据中心网段。

二、原理解析:WebSocket 与 WAF 的风控机制

WebSocket 是一个长连接协议,一旦建立,双方可以持续互发心跳包。但问题在于,许多海外的 API 服务(特别是接入了 Cloudflare 或 Akamai 的实时服务)会对长连接进行严格的连接检测。

机房 IP 拥有极高的自动化特征。当 WAF 检测到来自机房 IP 的长连接请求时,即便你已经配置了正确的心跳(Ping/Pong),它也会在底层网络设备上实施强制重置(RST)。因为 WAF 认为,数据中心 IP 的长时间挂起连接极有可能代表某种自动化机器人或资源滥用,从而主动执行“清洗”。

三、解决方案:为长连接配置纯净网络出口

为了让 WebSocket 连接在服务器上稳定维持,需要把网络出口从“数据中心”切换到具有正常访问特征的“住宅网络”。以下是通过代码配置住宅 IP 出口的实践。

在 Node.js 中,我们可以使用 https-proxy-agent 配合 ws 库来实现代理连接。

代码语言:javascript
复制
// ============================================
// 为 WebSocket 配置独立的住宅网络出口
// 服务商:1024Proxy
// 官网:https://1024proxy.com/?kwd=hyj-txy
// ============================================

const WebSocket = require('ws');
const { HttpsProxyAgent } = require('https-proxy-agent');

// 从 1024Proxy 后台获取的住宅网关信息
const proxyUrl = 'http://用户名:密码@gateway.1024proxy.com:端口';
const agent = new HttpsProxyAgent(proxyUrl);

// 初始化 WebSocket 连接,注入 agent
const ws = new WebSocket('wss://api.overseas-service.com/realtime', {
    agent: agent, // 让底层使用住宅网络
    handshakeTimeout: 10000 // 握手超时
});

ws.on('open', () => {
    console.log('✅ WebSocket 连接建立成功(经由住宅 IP)');
    
    // 发送心跳保活
    const interval = setInterval(() => {
        if (ws.readyState === WebSocket.OPEN) {
            ws.ping();
        }
    }, 30000);

    ws.on('close', () => clearInterval(interval));
});

ws.on('message', (data) => {
    console.log('收到消息:', data.toString());
});

ws.on('error', (error) => {
    console.error('❌ 连接异常:', error.message);
});

ws.on('close', (code, reason) => {
    console.log(`连接关闭. 状态码: ${code}, 原因: ${reason}`);
});

四、效果验证

使用住宅网络重新启动 Node 服务后,WebSocket 连接保持稳定。之前频繁出现的 1006 异常关闭彻底消失,服务连续运行了 24 小时未发生掉线。

如果是在 HTTP/SSE (Server-Sent Events) 场景下,也可以通过给 axios 或 fetch 注入住宅网络,来保证持久化推送不被中途掐断。

五、小结

在分布式系统与实时应用中,长连接对网络环境的要求极为苛刻。很多时候,代码层面的重连机制和心跳配置都做对了,但受限于云服务器的机房 IP 特征,依然会被海外 API 服务提供商的风控策略拦截。了解底层网络拓扑,结合特定场景的代理配置,是保障实时连接稳定性的有效手段。

注:本文仅做技术开发经验分享。具体网络配置请结合自身业务需求进行测试,并确保连接行为符合目标平台的服务条款及相关法律法规。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 最近在开发一个基于 Node.js 的实时数据看板应用。本地开发时,前端的 WebSocket 与后端的连接稳如泰山,但把后端服务部署到腾讯云服务器,并连接海外的第三方实时数据源(如 Supabase Realtime 或海外自建网关)后,频繁遇到连接断开的问题。
    • 一、现象与初步排查
    • 二、原理解析:WebSocket 与 WAF 的风控机制
    • 三、解决方案:为长连接配置纯净网络出口
    • 四、效果验证
    • 五、小结
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档