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

NestJS集成Socket.io对接币安WebSocket 前端仅收首条数据排查

问题核心原因
  • Socket.io 的 emit 回调是单次响应机制:前端调用 socket.emit('events', '', 回调) 时,传入的回调仅会接收服务端返回的一次确认响应,就算后端 Observable 持续产生数据,这个回调也只会触发一次。
  • NestJS @SubscribeMessage 装饰器默认逻辑:如果处理函数返回 Observable,默认仅会把第一个 next 产生的值作为响应返回给 emit 的回调,后续的 next 值不会主动推送给前端,需要手动调用推送方法才能下发。
  • 币安连接重复创建:当前每次客户端触发 events 事件都会新建一个币安 WebSocket 连接,并发高后会触发币安连接数限制,也会造成资源浪费。
修复方案

后端修改(Coin.gateway.ts)

调整为服务启动时仅初始化一次币安连接,收到币安推送的数据后主动通过 Socket.io 广播给所有客户端:

import { MessageBody, SubscribeMessage, WebSocketGateway, WebSocketServer, OnGatewayInit } from '@nestjs/websockets';
import { Server } from 'socket.io';
import { Coin } from './classes/coin';
import * as coinlist from './list/coins.json'

@WebSocketGateway(811, {transports: ['websocket', 'polling'], cors: true})
export class CoinGateway implements OnGatewayInit {

  @WebSocketServer()
  server: Server;
  private coins: Coin;

  // 网关初始化完成后自动执行,仅执行一次
  afterInit() {
    this.coins = new Coin(coinlist, 'usdt', 'miniTicker')
    // 订阅币安数据流,收到数据后主动推送给所有客户端
    this.coins.getCryptoData().subscribe((c) => {
      this.server.emit('coinData', c)
    })
  }

  @SubscribeMessage('events')
  handleMessage(@MessageBody() data: any) {
    // 仅返回单次订阅确认,持续数据通过上面的主动推送下发
    return {msg: '订阅成功'}
  }
}

前端修改(useEffect 逻辑)

新增对服务端主动推送事件的监听,不要依赖 emit 回调接收持续数据:

useEffect(() => {
    const socket = io('ws://localhost:811', {transports: ['websocket']})
    socket.on('connect', () => {
        console.log('Connection established from client')

        socket.emit('events', '', (res: any) => {
            console.log('订阅确认', res)
        })
        // 监听服务端主动推送的币安数据,每次推送都会触发
        socket.on('coinData', (data) => {
            console.log('收到币安数据', data)
        })
        const engine = socket.io.engine;
        console.log(engine.transport.name);

        engine.once("upgrade", () => {
            console.log(engine.transport.name);
        });

        engine.on("packetCreate", ({ type, data }) => {
            console.log('Stype', type)
            console.log('Sdata', data)
        });

    })
    // 组件卸载时主动断开连接,避免内存泄漏
    return () => {
        socket.disconnect()
    }
}, [])

额外Bug修复

Coin.ts 构造函数拼接币安连接url时,模板字符串末尾多了换行符,会导致连接请求异常,需要调整:

// 原来的错误写法
return `${c.symbol.toLowerCase()}${pair}@${method}
// 修改后
return `${c.symbol.toLowerCase()}${pair}@${method}`

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 21:45:04