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

如何在Redux Action中实现多动态链接WebSocket并区分币安数据Payload

解决币安WebSocket数据在Redux中区分币种的问题

你的核心问题是没有给每条WebSocket数据添加币种标识,导致Redux无法区分不同币种的payload,同时缺少合理的WebSocket实例管理和Redux状态结构设计。以下是具体的解决实现:

1. 修改Action Creator,给Payload添加币种标识

在dispatch时,把当前币种信息和数据一起传入payload,同时完善WebSocket的错误处理、实例管理和清理逻辑:

export function setupCoinSockets() {
  return function (dispatch: Dispatch) {
    // 存储socket实例,避免重复创建,方便后续关闭
    const sockets: Record<string, WebSocket> = {};

    coins.forEach(coin => {
      if (sockets[coin]) return;

      const socket = new WebSocket(`wss://stream.binance.com:9443/ws/${coin}@trade`);
      sockets[coin] = socket;

      socket.onmessage = (event) => {
        const tradeData = JSON.parse(event.data);
        dispatch({
          type: "WEBSOCKET_TRADE_DATA",
          payload: {
            coin, // 新增币种标识
            data: tradeData
          }
        });
      };

      // 错误处理
      socket.onerror = (error) => {
        dispatch({
          type: "WEBSOCKET_ERROR",
          payload: { coin, error }
        });
      };

      // 连接关闭时清理实例
      socket.onclose = () => {
        delete sockets[coin];
        // 可选:添加重连逻辑
      };
    });

    // 返回清理函数,组件卸载时关闭所有socket,防止内存泄漏
    return () => {
      Object.values(sockets).forEach(socket => socket.close());
    };
  };
}

2. 设计合理的Redux状态结构

使用对象以币种为key存储数据,确保不同币种的数据相互独立,便于视图层获取:

// 初始状态
const initialState = {
  tradeData: {}, // 结构:{ [币种名称: string]: 交易数据 }
  errors: {} // 存储各币种的连接错误
};

function webSocketReducer(state = initialState, action) {
  switch (action.type) {
    case "WEBSOCKET_TRADE_DATA": {
      const { coin, data } = action.payload;
      return {
        ...state,
        tradeData: {
          ...state.tradeData,
          [coin]: data // 用币种作为key,更新对应数据
        }
      };
    }
    case "WEBSOCKET_ERROR": {
      const { coin, error } = action.payload;
      return {
        ...state,
        errors: {
          ...state.errors,
          [coin]: error
        }
      };
    }
    default:
      return state;
  }
}

3. 视图层展示对应币种的数据

通过useSelector精准获取指定币种的交易数据:

import { useSelector } from "react-redux";

// 单个币种的展示组件
function CoinTradeCard({ coin }) {
  const tradeData = useSelector(state => state.webSocket.tradeData[coin]);

  if (!tradeData) return <div>加载中...</div>;

  return (
    <div className="coin-card">
      <h3>{coin.toUpperCase()}</h3>
      <p>最新成交价: {tradeData.p}</p>
      <p>成交量: {tradeData.q}</p>
      <p>交易时间: {new Date(tradeData.T).toLocaleString()}</p>
    </div>
  );
}

// 批量展示所有币种
function AllCoinsDisplay() {
  return (
    <div className="coins-container">
      {coins.map(coin => (
        <CoinTradeCard key={coin} coin={coin} />
      ))}
    </div>
  );
}

关键优化点说明

  • 币种标识绑定:每条payload都携带对应的币种名称,从根源解决数据混淆问题。
  • 结构化状态存储:用对象key-value的方式管理多币种数据,查询和更新效率更高。
  • WebSocket生命周期管理:保存实例避免重复连接,添加关闭清理和错误处理,防止内存泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 21:24:23