앱 실시간 갱신 수정
This commit is contained in:
@@ -1,21 +1,18 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { isDesktop } from '../utils/platform';
|
||||
import { getDesktopAppVersion, syncDesktopMainWindowTitle } from '../utils/desktopBridge';
|
||||
import { readBakedDesktopAppVersion } from '../utils/desktopAppVersion';
|
||||
|
||||
/** Desktop — 네이티브 창 타이틀·document.title을 GoldenChart (vX.Y.Z) 로 맞춤 */
|
||||
/** Desktop — Tauri getVersion() 기준 (설치된 앱 버전). baked 0.1.4 등 git 고정값 사용 안 함 */
|
||||
export function useDesktopAppTitle(): string | null {
|
||||
const [version, setVersion] = useState<string | null>(() =>
|
||||
isDesktop() ? readBakedDesktopAppVersion() : null,
|
||||
);
|
||||
const [version, setVersion] = useState<string | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isDesktop()) return;
|
||||
let cancelled = false;
|
||||
void (async () => {
|
||||
const v = (await getDesktopAppVersion()) ?? readBakedDesktopAppVersion();
|
||||
if (cancelled || !v) return;
|
||||
setVersion(v);
|
||||
const v = await getDesktopAppVersion();
|
||||
if (cancelled || !v?.trim()) return;
|
||||
setVersion(v.trim());
|
||||
await syncDesktopMainWindowTitle();
|
||||
})();
|
||||
return () => { cancelled = true; };
|
||||
|
||||
@@ -61,6 +61,13 @@ export function getStompSockJsUrl(): string {
|
||||
return path;
|
||||
}
|
||||
|
||||
/** Desktop — 순수 WebSocket STOMP (SockJS 미사용) */
|
||||
export function getStompNativeWebSocketUrl(): string {
|
||||
const secureOrigin = getSecureApiOrigin().replace(/^http:\/\//i, 'https://');
|
||||
const wsOrigin = secureOrigin.replace(/^https:\/\//i, 'wss://');
|
||||
return `${wsOrigin}/api/ws/trading/ws`;
|
||||
}
|
||||
|
||||
// UUID 생성 — HTTPS/localhost: crypto.randomUUID() 사용, HTTP: 폴리필
|
||||
function generateUUID(): string {
|
||||
if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
/**
|
||||
* 차트·실시간 전략용 STOMP 단일 연결 (SockJS 1회).
|
||||
* 훅마다 StompClient 를 만들면 "closed before connection is established" 가 반복된다.
|
||||
* 차트·실시간 전략용 STOMP 단일 연결.
|
||||
* 웹: SockJS 1회 / Desktop: 순수 WebSocket (cross-origin SockJS 세션 불가)
|
||||
*/
|
||||
import { Client as StompClient, IMessage, StompSubscription } from '@stomp/stompjs';
|
||||
import SockJS from 'sockjs-client';
|
||||
import { getStompSockJsUrl } from './backendApi';
|
||||
import { getStompNativeWebSocketUrl, getStompSockJsUrl } from './backendApi';
|
||||
import { isDesktop } from './platform';
|
||||
|
||||
type MessageHandler = (msg: IMessage) => void;
|
||||
type ConnectionListener = (connected: boolean) => void;
|
||||
@@ -49,11 +50,12 @@ function resubscribeAll(): void {
|
||||
}
|
||||
}
|
||||
|
||||
function getOrCreateClient(): StompClient {
|
||||
if (client) return client;
|
||||
function stompConnectLabel(): string {
|
||||
return isDesktop() ? getStompNativeWebSocketUrl() : getStompSockJsUrl();
|
||||
}
|
||||
|
||||
client = new StompClient({
|
||||
webSocketFactory: () => new SockJS(getStompSockJsUrl()),
|
||||
function createStompClient(): StompClient {
|
||||
const shared = {
|
||||
reconnectDelay: 5000,
|
||||
heartbeatIncoming: 10_000,
|
||||
heartbeatOutgoing: 10_000,
|
||||
@@ -68,11 +70,11 @@ function getOrCreateClient(): StompClient {
|
||||
entry.stompSub = undefined;
|
||||
}
|
||||
},
|
||||
onStompError: frame => {
|
||||
onStompError: (frame: { headers?: { message?: string } }) => {
|
||||
console.warn('[stompChartBroker] STOMP error', frame.headers?.message ?? frame);
|
||||
},
|
||||
onWebSocketError: ev => {
|
||||
console.warn('[stompChartBroker] WebSocket error', getStompSockJsUrl(), ev);
|
||||
onWebSocketError: (ev: Event) => {
|
||||
console.warn('[stompChartBroker] WebSocket error', stompConnectLabel(), ev);
|
||||
},
|
||||
onWebSocketClose: () => {
|
||||
notifyConnection(false);
|
||||
@@ -80,7 +82,23 @@ function getOrCreateClient(): StompClient {
|
||||
entry.stompSub = undefined;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
if (isDesktop()) {
|
||||
const brokerURL = getStompNativeWebSocketUrl();
|
||||
return new StompClient({ ...shared, brokerURL });
|
||||
}
|
||||
|
||||
const sockJsUrl = getStompSockJsUrl();
|
||||
return new StompClient({
|
||||
...shared,
|
||||
webSocketFactory: () => new SockJS(sockJsUrl),
|
||||
});
|
||||
}
|
||||
|
||||
function getOrCreateClient(): StompClient {
|
||||
if (client) return client;
|
||||
client = createStompClient();
|
||||
return client;
|
||||
}
|
||||
|
||||
@@ -96,7 +114,6 @@ function scheduleDisconnect(): void {
|
||||
disconnectTimer = null;
|
||||
if (handlerCount() > 0) return;
|
||||
if (!client?.active) return;
|
||||
// 연결 수립 중 deactivate 하면 "closed before connection is established" 발생
|
||||
if (!connected) {
|
||||
scheduleDisconnect();
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user