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
相关产品推荐
相关产品推荐

