스킬 정리 및 리팩토링
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { create } from "zustand";
|
||||
import { buildKisErrorDetail } from "@/lib/kis/error-codes";
|
||||
import { useKisRuntimeStore } from "@/features/settings/store/use-kis-runtime-store";
|
||||
import { buildKisRealtimeMessage } from "@/features/kis-realtime/utils/websocketUtils";
|
||||
|
||||
@@ -63,6 +64,21 @@ const RECONNECT_BASE_DELAY_MS = 1_000;
|
||||
const RECONNECT_MAX_DELAY_MS = 30_000;
|
||||
const RECONNECT_JITTER_MS = 300;
|
||||
|
||||
function isKisWsDebugEnabled() {
|
||||
if (typeof window === "undefined") return false;
|
||||
return window.localStorage.getItem("KIS_WS_DEBUG") === "1";
|
||||
}
|
||||
|
||||
function wsDebugLog(...args: unknown[]) {
|
||||
if (!isKisWsDebugEnabled()) return;
|
||||
console.log(...args);
|
||||
}
|
||||
|
||||
function wsDebugWarn(...args: unknown[]) {
|
||||
if (!isKisWsDebugEnabled()) return;
|
||||
console.warn(...args);
|
||||
}
|
||||
|
||||
export const useKisWebSocketStore = create<KisWebSocketState>((set, get) => ({
|
||||
isConnected: false,
|
||||
error: null,
|
||||
@@ -105,7 +121,7 @@ export const useKisWebSocketStore = create<KisWebSocketState>((set, get) => ({
|
||||
// 소켓 생성
|
||||
// socket 변수에 할당하기 전에 로컬 변수로 제어하여 이벤트 핸들러 클로저 문제 방지
|
||||
const ws = new WebSocket(wsConnection.wsUrl);
|
||||
console.log("[KisWebSocket] Connecting to:", wsConnection.wsUrl);
|
||||
wsDebugLog("[KisWebSocket] Connecting to:", wsConnection.wsUrl);
|
||||
socket = ws;
|
||||
|
||||
ws.onopen = () => {
|
||||
@@ -116,7 +132,7 @@ export const useKisWebSocketStore = create<KisWebSocketState>((set, get) => ({
|
||||
|
||||
set({ isConnected: true, error: null });
|
||||
reconnectAttempt = 0;
|
||||
console.log("[KisWebSocket] Connected");
|
||||
wsDebugLog("[KisWebSocket] Connected");
|
||||
|
||||
// 재연결 시 기존 구독 복구
|
||||
const approvalKey = wsConnection.approvalKey;
|
||||
@@ -147,7 +163,7 @@ export const useKisWebSocketStore = create<KisWebSocketState>((set, get) => ({
|
||||
if (canAutoReconnect) {
|
||||
reconnectAttempt += 1;
|
||||
const delayMs = getReconnectDelayMs(reconnectAttempt);
|
||||
console.warn(
|
||||
wsDebugWarn(
|
||||
`[KisWebSocket] Disconnected (code=${event.code}, reason=${event.reason || "none"}, wasClean=${event.wasClean}) -> reconnect in ${delayMs}ms (attempt ${reconnectAttempt}/${MAX_AUTO_RECONNECT_ATTEMPTS})`,
|
||||
);
|
||||
|
||||
@@ -170,7 +186,7 @@ export const useKisWebSocketStore = create<KisWebSocketState>((set, get) => ({
|
||||
}
|
||||
|
||||
reconnectAttempt = 0;
|
||||
console.log(
|
||||
wsDebugLog(
|
||||
`[KisWebSocket] Disconnected (code=${event.code}, reason=${event.reason || "none"})`,
|
||||
);
|
||||
}
|
||||
@@ -221,15 +237,15 @@ export const useKisWebSocketStore = create<KisWebSocketState>((set, get) => ({
|
||||
// KIS 서버가 세션을 정리하는 데 최소 10~30초가 필요하므로
|
||||
// 충분한 대기 후 재연결합니다.
|
||||
if (control.msgCd === "OPSP8996") {
|
||||
const now = Date.now();
|
||||
if (now - lastAppKeyConflictAt > 5_000) {
|
||||
lastAppKeyConflictAt = now;
|
||||
console.warn(
|
||||
"[KisWebSocket] ALREADY IN USE appkey - 현재 소켓을 닫고 30초 후 재연결합니다.",
|
||||
);
|
||||
// 현재 소켓을 즉시 닫아 서버 측 세션 정리 유도
|
||||
if (socket === ws && ws.readyState === WebSocket.OPEN) {
|
||||
ws.close(1000, "ALREADY IN USE - graceful close");
|
||||
const now = Date.now();
|
||||
if (now - lastAppKeyConflictAt > 5_000) {
|
||||
lastAppKeyConflictAt = now;
|
||||
wsDebugWarn(
|
||||
"[KisWebSocket] ALREADY IN USE appkey - 현재 소켓을 닫고 30초 후 재연결합니다.",
|
||||
);
|
||||
// 현재 소켓을 즉시 닫아 서버 측 세션 정리 유도
|
||||
if (socket === ws && ws.readyState === WebSocket.OPEN) {
|
||||
ws.close(1000, "ALREADY IN USE - graceful close");
|
||||
}
|
||||
window.clearTimeout(reconnectRetryTimer);
|
||||
reconnectRetryTimer = window.setTimeout(() => {
|
||||
@@ -374,11 +390,11 @@ function sendSubscription(
|
||||
try {
|
||||
const msg = buildKisRealtimeMessage(appKey, symbol, trId, trType);
|
||||
ws.send(JSON.stringify(msg));
|
||||
console.debug(
|
||||
wsDebugLog(
|
||||
`[KisWebSocket] ${trType === "1" ? "Sub" : "Unsub"} ${trId} ${symbol}`,
|
||||
);
|
||||
} catch (e) {
|
||||
console.warn("[KisWebSocket] Send error", e);
|
||||
wsDebugWarn("[KisWebSocket] Send error", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -440,7 +456,10 @@ function buildControlErrorMessage(message: KisWsControlMessage) {
|
||||
if (message.msgCd === "OPSP8996") {
|
||||
return "실시간 연결이 다른 세션과 충돌해 재연결을 시도합니다.";
|
||||
}
|
||||
const detail = [message.msg1, message.msgCd].filter(Boolean).join(" / ");
|
||||
const detail = buildKisErrorDetail({
|
||||
message: message.msg1,
|
||||
msgCode: message.msgCd,
|
||||
});
|
||||
return detail
|
||||
? `실시간 제어 메시지 오류: ${detail}`
|
||||
: "실시간 제어 메시지 오류";
|
||||
|
||||
Reference in New Issue
Block a user