如何将WebSocket获取的币安交易数据转发至客户端?
嘿,你的思路方向是对的,但当前实现存在一个容易踩坑的小问题,咱们一步步梳理并优化:
需求与架构回顾
你想要的是这样的数据流:
- 从币安WebSocket服务器拉取实时交易数据
- 本地搭建WebSocket中转服务器,把数据推送给所有连接的浏览器客户端
- 最终浏览器能实时打印每条交易消息
现有实现的潜在问题
你当前的代码是在connection事件(每次有新客户端连上来时)给binanceWS绑定message监听器,这会导致:每新增一个客户端,币安的消息监听器就会多绑定一次。比如有3个客户端连接后,币安每发一条数据,同一个客户端会收到3次重复消息,这显然不是你想要的效果。
优化后的可靠实现方案
我们只需要给币安的WebSocket绑定一次消息监听器,然后维护一个活跃客户端集合,收到数据时遍历集合转发给所有在线客户端即可:
"use strict"; const WebSocket = require("ws"); // 1. 连接币安WebSocket获取实时交易数据 const binanceWS = new WebSocket("wss://stream.binance.com:9443/ws/stratbtc@trade"); binanceWS.on("open", function open() { console.log("已成功连接到币安WebSocket服务器"); }); // 2. 启动本地WebSocket中转服务器 const wss = new WebSocket.Server({ port: 8080 }); console.log("本地WebSocket中转服务器已启动,监听端口8080"); // 用Set存储所有活跃的客户端连接,方便添加、移除和遍历 const activeClients = new Set(); // 处理新客户端连接 wss.on('connection', function connection(ws) { console.log("新客户端已连接"); activeClients.add(ws); // 客户端断开连接时,从集合中移除,避免无效连接占用资源 ws.on('close', function close() { console.log("客户端已断开连接"); activeClients.delete(ws); }); // 可选:处理客户端主动发来的消息(如果需要双向通信) ws.on('message', function incoming(message) { console.log('收到客户端消息: %s', message); }); }); // 3. 币安收到数据时,统一转发给所有在线客户端 binanceWS.on("message", function incoming(data) { activeClients.forEach((client) => { // 发送前检查客户端连接状态,避免向已断开的连接发送数据报错 if (client.readyState === WebSocket.OPEN) { client.send(data); } }); });
关键优化点
- 用
Set管理客户端连接:自动去重,增删操作高效 - 单次绑定币安消息监听器:避免重复推送数据
- 检查连接状态:防止向已断开的客户端发送数据引发错误
浏览器客户端测试代码
你可以用下面的HTML在浏览器中测试,打开后会自动连接本地服务器并打印实时交易数据:
<!DOCTYPE html> <html> <body> <script> const ws = new WebSocket('ws://localhost:8080'); ws.onmessage = function(event) { // 解析JSON格式的交易数据并打印 console.log('实时交易数据:', JSON.parse(event.data)); }; ws.onopen = function() { console.log('已连接到本地WebSocket中转服务器'); }; ws.onclose = function() { console.log('与服务器断开连接'); }; </script> </body> </html>
内容的提问来源于stack exchange,提问作者quartaela
相关产品推荐
相关产品推荐

