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

Node.js HTTP模块无法接收WebSocket请求(使用https-proxy-agent)

我来帮你分析下这个问题,以及如何解决它:

问题核心原因

WebSocket 请求本质是基于 HTTP 协议的握手请求,你的 HTTP 服务器没收到请求,大概率是两个问题:

  1. 客户端的代理配置有误,导致请求根本没发到你的 9999 端口
  2. 就算请求到达了,你的 HTTP 服务器没有处理 WebSocket 特有的upgrade事件,握手失败后客户端会立刻断开,你可能没来得及看到日志
解决方案

我们需要先让 HTTP 服务器正确识别并处理 WebSocket 握手,再修正客户端的代理配置。

1. 修复 HTTP 服务器,支持 WebSocket 转发

原始代码只监听了普通 HTTP 请求的request事件,但 WebSocket 握手会触发upgrade事件,我们需要单独处理这个事件来完成转发:

const http = require('http');
const WebSocket = require('ws');

// 创建基础 HTTP 服务器
const server = http.createServer((req, res) => {
  console.log('收到普通 HTTP 请求:', req.method, req.url);
  res.writeHead(200);
  res.end('这是 HTTP 服务器');
});

// 处理 WebSocket 握手与转发
server.on('upgrade', (req, socket, head) => {
  console.log('收到 WebSocket 握手请求:', req.url);
  
  // 连接到目标端口的 WebSocket 服务(示例目标端口为 8080)
  const targetWs = new WebSocket(`ws://localhost:8080${req.url}`);
  
  // 完成客户端握手响应
  targetWs.on('open', () => {
    socket.write(
      `HTTP/1.1 101 Switching Protocols\r\n` +
      `Upgrade: websocket\r\n` +
      `Connection: Upgrade\r\n` +
      `Sec-WebSocket-Accept: ${req.headers['sec-websocket-accept']}\r\n\r\n`
    );
    // 双向转发数据
    socket.pipe(targetWs);
    targetWs.pipe(socket);
  });
  
  // 错误处理,避免连接泄漏
  targetWs.on('error', (err) => {
    console.error('连接目标 WebSocket 失败:', err);
    socket.destroy();
  });
  
  socket.on('error', (err) => {
    console.error('客户端连接错误:', err);
    targetWs.close();
  });
});

server.listen(9999, () => {
  console.log('HTTP 服务器监听在 9999 端口');
});

如果你想更简洁,可以用ws-proxy库简化转发逻辑:
先安装依赖:

npm install ws-proxy

再修改服务器代码:

const http = require('http');
const { createProxy } = require('ws-proxy');

const server = http.createServer((req, res) => {
  console.log('收到普通 HTTP 请求:', req.method, req.url);
  res.end('Hello HTTP');
});

// 创建 WebSocket 代理,转发到目标端口 8080
const proxy = createProxy({ target: 'ws://localhost:8080' });
server.on('upgrade', proxy.upgrade);

server.listen(9999);

2. 修正客户端代理配置

你的客户端用了HttpsProxyAgent,但如果你的转发服务器是 HTTP 协议(而非 HTTPS),应该用HttpProxyAgent,正确代码如下:

const WebSocket = require('ws');
const { HttpProxyAgent } = require('http-proxy-agent');

// 配置代理指向你的 9999 端口服务器
const agent = new HttpProxyAgent('http://localhost:9999');

// 通过代理连接目标 WebSocket 服务
const ws = new WebSocket('ws://localhost:8080/your-path', { agent });

ws.on('open', () => {
  console.log('WebSocket 连接成功');
  ws.send('Hello from client');
});

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

ws.on('error', (err) => {
  console.error('WebSocket 错误:', err);
});

ws.on('close', () => {
  console.log('WebSocket 连接关闭');
});
关键注意事项
  • 只有当你的转发服务器是 HTTPS 协议时,才需要用HttpsProxyAgent,否则用HttpProxyAgent
  • WebSocket 请求不会触发createServer的回调函数,必须监听upgrade事件才能捕获
  • 日志要打印在upgrade事件处理逻辑里,才能看到 WebSocket 请求的信息

这样修改后,你的 HTTP 服务器就能正常接收并转发 WebSocket 请求了。

内容的提问来源于stack exchange,提问作者Aero Wang

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 03:58:13