重构 WebSocket 推送服务:统一使用 /ws 路径和 channel 订阅模式

- 后端重构:
  - 统一 WebSocket 路径为 /ws,通过 channel 区分不同推送服务
  - 实现 UnifiedWebSocketHandler 统一处理所有推送频道
  - 实现 WebSocketSubscriptionService 管理订阅和推送
  - 消息类型改为 int 类型(1:SUB, 2:UNSUB, 3:DATA, 4:SUB_ACK, 5:PING, 6:PONG)
  - status 字段改为 int 类型(0: success, 非0: error)
  - 移除旧的 /ws/positions 路由和 PositionWebSocketHandler
  - 修复首推数据:订阅 position 频道后立即发送全量数据

- 前端重构:
  - 实现全局 WebSocket 管理器(单例模式)
  - 应用启动时立即建立全局 WebSocket 连接
  - 实现 useWebSocketSubscription hook 用于订阅频道
  - PositionList 完全依赖 WebSocket 推送,移除 HTTP 轮询
  - 添加连接状态显示和自动重连机制
  - 实现心跳保活机制(PING/PONG)

- 配置更新:
  - 添加 WebSocket 相关配置项
  - 更新 vite.config.ts 添加 /ws 代理配置
This commit is contained in:
WrBug
2025-11-27 02:56:24 +08:00
parent f53ba1ca49
commit 47357995af
16 changed files with 2529 additions and 101 deletions
+23
View File
@@ -187,3 +187,26 @@ export interface PositionListResponse {
historyPositions: AccountPosition[]
}
/**
* 仓位推送消息类型
*/
export type PositionPushMessageType = 'FULL' | 'INCREMENTAL'
/**
* 仓位推送消息
*/
export interface PositionPushMessage {
type: PositionPushMessageType // 消息类型:FULL(全量)或 INCREMENTAL(增量)
timestamp: number // 消息时间戳
currentPositions?: AccountPosition[] // 当前仓位列表(全量或增量)
historyPositions?: AccountPosition[] // 历史仓位列表(全量或增量)
removedPositionKeys?: string[] // 已删除的仓位键(仅增量推送时使用)
}
/**
* 获取仓位唯一键
*/
export function getPositionKey(position: AccountPosition): string {
return `${position.accountId}-${position.marketId}-${position.side}`
}