diff --git a/src/tradingview/datafeed.ts b/src/tradingview/datafeed.ts index 4d85311..b5b2603 100644 --- a/src/tradingview/datafeed.ts +++ b/src/tradingview/datafeed.ts @@ -13,15 +13,14 @@ import type { SubscribeBarsCallback, } from "#/datafeed-api"; import type { MarketDataStreaming } from "@/api/types"; -import { client } from "@/api"; +import { tradeWebSocket } from "./websocket"; /** * 自定义 TradingView Datafeed 实现 * 用于从后端 API 获取 K 线数据 */ export class RWADatafeed extends Datafeeds.UDFCompatibleDatafeed { - private subscribers: Map = new Map(); - private wsConnections: Map = new Map(); + private subscribers: Map = new Map(); constructor(apiUrl: string) { super(apiUrl); @@ -203,28 +202,30 @@ export class RWADatafeed extends Datafeeds.UDFCompatibleDatafeed { subscriberUID: string, onResetCacheNeededCallback: () => void, ): void { - console.log("[RWADatafeed]: subscribeBars", { - symbol: symbolInfo.name, - resolution, - subscriberUID, - }); - this.subscribers.set(subscriberUID, { callback: onTick, resolution }); - const ws = client.api.market_data.streaming.subscribe(); - this.wsConnections.set(subscriberUID, ws); - ws.on("open", () => { - ws.send({ type: "subscribe", subscriberUID, symbol: symbolInfo.name, resolution }); + console.log("[RWADatafeed]: subscribeBars", { symbol: symbolInfo.name, resolution, subscriberUID }); + + this.subscribers.set(subscriberUID, { callback: onTick, resolution, symbol: symbolInfo.name }); + const wsConnection = tradeWebSocket.getSocket(); + + wsConnection.send({ + action: "subscribe", + channels: [{ + name: "bar", + symbol: symbolInfo.name, + }], }); - ws.subscribe((message) => { - if (message.data.type !== "bar") + wsConnection.subscribe((message) => { + const data = message.data as any; + if (data.type !== "bar") return; const bar: Bar = { - time: message.data.bar.time, - open: message.data.bar.open, - high: message.data.bar.high, - low: message.data.bar.low, - close: message.data.bar.close, - volume: message.data.bar.volume, + time: data.bar.time, + open: data.bar.open, + high: data.bar.high, + low: data.bar.low, + close: data.bar.close, + volume: data.bar.volume, }; onTick(bar); }); @@ -235,10 +236,14 @@ export class RWADatafeed extends Datafeeds.UDFCompatibleDatafeed { */ unsubscribeBars(subscriberUID: string): void { console.log("[RWADatafeed]: unsubscribeBars", subscriberUID); - const ws = this.wsConnections.get(subscriberUID); - if (ws) { - ws.close(); - this.wsConnections.delete(subscriberUID); - } + const subscriber = this.subscribers.get(subscriberUID); + const wsConnection = tradeWebSocket.getSocket(); + wsConnection.send({ + action: "unsubscribe", + channels: [{ + name: "bar", + symbol: subscriber?.symbol || "", + }], + }); } } diff --git a/src/tradingview/websocket.ts b/src/tradingview/websocket.ts new file mode 100644 index 0000000..4f9a9c5 --- /dev/null +++ b/src/tradingview/websocket.ts @@ -0,0 +1,24 @@ +import type { MarketDataStreaming } from "@/api/types"; +import { client } from "@/api"; + +export class TradeWebSocket { + public socket: MarketDataStreaming | null = null; + constructor() { + if (!this.socket) { + this.socket = client.api.market_data.streaming.subscribe(); + } + } + + public getSocket(): MarketDataStreaming { + return this.socket!; + } + + public closeSocket() { + if (this.socket) { + this.socket.close(); + this.socket = null; + } + } +} + +export const tradeWebSocket = new TradeWebSocket(); diff --git a/src/views/wallet/transfer.vue b/src/views/wallet/transfer.vue index 4f34b1e..2a10616 100644 --- a/src/views/wallet/transfer.vue +++ b/src/views/wallet/transfer.vue @@ -1,13 +1,15 @@