64 lines
2.2 KiB
TypeScript
64 lines
2.2 KiB
TypeScript
|
|
import { useRef, useEffect } from "react";
|
||
|
|
import type { KisRuntimeCredentials } from "@/features/settings/store/use-kis-runtime-store";
|
||
|
|
import type { DashboardStockOrderBookResponse } from "@/features/trade/types/trade.types";
|
||
|
|
import { useKisWebSocketStore } from "@/features/kis-realtime/stores/kisWebSocketStore";
|
||
|
|
import {
|
||
|
|
parseKisRealtimeOrderbook,
|
||
|
|
resolveOrderBookTrIds,
|
||
|
|
} from "@/features/trade/utils/kisRealtimeUtils";
|
||
|
|
import type { DomesticKisSession } from "@/lib/kis/domestic-market-session";
|
||
|
|
|
||
|
|
interface UseOrderbookSubscriptionParams {
|
||
|
|
symbol: string | undefined; // orderBookSymbol
|
||
|
|
isVerified: boolean;
|
||
|
|
credentials: KisRuntimeCredentials | null;
|
||
|
|
marketSession: DomesticKisSession;
|
||
|
|
onOrderBookMessage?: (data: DashboardStockOrderBookResponse) => void;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @description 실시간 호가(Orderbook) 구독 로직을 담당하는 훅입니다.
|
||
|
|
* - 호가 데이터는 빈도가 매우 높으므로 별도의 상태(state)에 저장하지 않고,
|
||
|
|
* - 콜백 함수(onOrderBookMessage)를 통해 상위 컴포넌트로 데이터를 직접 전달합니다.
|
||
|
|
* - 이를 통해 불필요한 리렌더링을 방지합니다.
|
||
|
|
*/
|
||
|
|
export function useOrderbookSubscription({
|
||
|
|
symbol,
|
||
|
|
isVerified,
|
||
|
|
credentials,
|
||
|
|
marketSession,
|
||
|
|
onOrderBookMessage,
|
||
|
|
}: UseOrderbookSubscriptionParams) {
|
||
|
|
const { subscribe, connect } = useKisWebSocketStore();
|
||
|
|
const onOrderBookMessageRef = useRef(onOrderBookMessage);
|
||
|
|
|
||
|
|
useEffect(() => {
|
||
|
|
onOrderBookMessageRef.current = onOrderBookMessage;
|
||
|
|
}, [onOrderBookMessage]);
|
||
|
|
|
||
|
|
useEffect(() => {
|
||
|
|
if (!symbol || !isVerified || !credentials) return;
|
||
|
|
|
||
|
|
connect();
|
||
|
|
|
||
|
|
const trIds = resolveOrderBookTrIds(credentials.tradingEnv, marketSession);
|
||
|
|
const unsubscribers: Array<() => void> = [];
|
||
|
|
|
||
|
|
const handleOrderBookMessage = (data: string) => {
|
||
|
|
const ob = parseKisRealtimeOrderbook(data, symbol);
|
||
|
|
if (ob) {
|
||
|
|
ob.tradingEnv = credentials.tradingEnv;
|
||
|
|
onOrderBookMessageRef.current?.(ob);
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
for (const trId of trIds) {
|
||
|
|
unsubscribers.push(subscribe(trId, symbol, handleOrderBookMessage));
|
||
|
|
}
|
||
|
|
|
||
|
|
return () => {
|
||
|
|
unsubscribers.forEach((unsub) => unsub());
|
||
|
|
};
|
||
|
|
}, [symbol, isVerified, credentials, marketSession, connect, subscribe]);
|
||
|
|
}
|