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

Express框架下使用WebSockets实现Node服务代理双向通信

Express + WebSocket 双向转发实现方案

你需要在可控的servertest.js服务上实现WebSocket透传代理,不需要修改无管控权限的extServer.js任何代码,即可满足「网页→servertest→extServer」全链路双向通信要求,拓扑如下:

---------           ---------------         --------------
     | Webpage | <------>| servertest.js |<----->| extServer.js |
      ---------           ---------------         --------------

前置依赖安装

在servertest.js所在目录执行命令安装所需包:

npm install express ws
  • express:用于托管前端静态页面、处理普通HTTP请求
  • ws:轻量WebSocket实现,同时支持服务端、客户端能力,用来对接浏览器和extServer两端

servertest.js 完整实现代码

注意不要直接用express.listen()启动服务,需要将Express挂载到原生HTTP Server上,才能让WebSocket服务和HTTP服务共享8080端口:

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

const app = express();
// 把Express挂载到原生HTTP服务器
const server = http.createServer(app);

// 托管前端静态文件,比如把网页放在当前目录的public文件夹下
app.use(express.static('public'));

// 初始化WebSocket服务端,和HTTP服务共享8080端口,监听/ws路径避免和静态资源冲突
const wss = new WebSocket.Server({ server, path: '/ws' });

wss.on('connection', (browserWs) => {
  // 每当有浏览器连入,立刻建立到extServer的WebSocket连接
  const extWs = new WebSocket('ws://127.0.0.1:3000');

  // 1. 浏览器 → extServer 消息转发
  browserWs.on('message', (data, isBinary) => {
    // 确认extServer连接正常时才转发
    if (extWs.readyState === WebSocket.OPEN) {
      extWs.send(data, { binary: isBinary });
    }
  });

  // 2. extServer → 浏览器 消息转发
  extWs.on('message', (data, isBinary) => {
    if (browserWs.readyState === WebSocket.OPEN) {
      browserWs.send(data, { binary: isBinary });
    }
  });

  // 3. 连接断开/异常处理:任意一端断开,主动关闭另一端连接,避免资源泄漏
  const handleClose = () => {
    if (browserWs.readyState === WebSocket.OPEN) browserWs.close();
    if (extWs.readyState === WebSocket.OPEN) extWs.close();
  };

  browserWs.on('close', handleClose);
  extWs.on('close', handleClose);
  browserWs.on('error', handleClose);
  extWs.on('error', handleClose);
});

// 启动服务监听8080端口
server.listen(8080, () => {
  console.log('servertest 运行在 http://localhost:8080');
});

前端网页连接示例

把下面的代码放在public/index.html中,网页只需要连当前域名下的servertest服务即可,不需要直接访问3000端口:

<!DOCTYPE html>
<html>
<head>
  <title>WebSocket 测试页</title>
</head>
<body>
  <script>
    // 连接到同域下servertest暴露的/ws端点
    const ws = new WebSocket(`ws://${window.location.host}/ws`);
    
    ws.onopen = () => {
      console.log('已连接到服务端');
      ws.send('测试消息从网页发出');
    };

    ws.onmessage = (event) => {
      console.log('收到服务端返回消息:', event.data);
    };

    ws.onclose = () => {
      console.log('连接已断开');
    };
  </script>
</body>
</html>

注意事项

  • 每个浏览器连接会对应独立的extServer连接,不要复用全局extServer连接,否则多用户场景下会出现消息串流问题
  • 转发消息时直接透传原始二进制/文本数据即可,不要额外做序列化、格式转换,避免和extServer的协议不兼容
  • 如果extServer的WebSocket服务挂载在非根路径,只需要修改extWs初始化时的地址即可,比如ws://127.0.0.1:3000/socket
  • 启动服务后直接访问http://localhost:8080即可打开前端页面,所有WebSocket流量会自动经过servertest转发到3000端口的extServer

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 18:42:33