From ee755dc36e75c24cda3e5cef005d955261a942d1 Mon Sep 17 00:00:00 2001 From: Seven Date: Tue, 13 Jan 2026 18:56:47 +0700 Subject: [PATCH] =?UTF-8?q?feat:=20=E9=87=8D=E6=9E=84=20RWADatafeed=20?= =?UTF-8?q?=E4=BB=A5=E4=BD=BF=E7=94=A8=20TradeWebSocket=EF=BC=8C=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E8=AE=A2=E9=98=85=E5=92=8C=E5=8F=96=E6=B6=88=E8=AE=A2?= =?UTF-8?q?=E9=98=85=E9=80=BB=E8=BE=91=EF=BC=9B=E5=9C=A8=E8=BD=AC=E8=B4=A6?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=E4=B8=AD=E6=B7=BB=E5=8A=A0=E5=B8=81=E7=A7=8D?= =?UTF-8?q?=E9=80=89=E6=8B=A9=E5=92=8C=E5=8F=AF=E7=94=A8=E4=BD=99=E9=A2=9D?= =?UTF-8?q?=E5=90=8C=E6=AD=A5=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/tradingview/datafeed.ts | 57 ++++++++++--------- src/tradingview/websocket.ts | 24 ++++++++ src/views/wallet/transfer.vue | 100 +++++++++++++++++++++++----------- vite.config.ts | 3 +- 4 files changed, 125 insertions(+), 59 deletions(-) create mode 100644 src/tradingview/websocket.ts 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 @@