웹소켓 적용중
This commit is contained in:
@@ -6,16 +6,32 @@ interface WebSocketMessage {
|
||||
data: unknown
|
||||
}
|
||||
|
||||
export const useWebSocket = (clientId: string) => {
|
||||
const [socket, setSocket] = useState<WebSocket | null>(null)
|
||||
interface UseWebSocketOptions {
|
||||
/** market_update 메시지 전용 콜백 (배열 누적 방지 — 실시간 틱 전용) */
|
||||
onMarketUpdate?: (data: unknown) => void
|
||||
/** chart_data 메시지 전용 콜백 (배열 누적 방지 — 차트 로드 전용) */
|
||||
onChartData?: (data: unknown) => void
|
||||
}
|
||||
|
||||
export const useWebSocket = (clientId: string, options?: UseWebSocketOptions) => {
|
||||
const [messages, setMessages] = useState<WebSocketMessage[]>([])
|
||||
const [connected, setConnected] = useState(false)
|
||||
const reconnectTimeoutRef = useRef<NodeJS.Timeout | null>(null)
|
||||
const pingIntervalRef = useRef<NodeJS.Timeout | null>(null)
|
||||
const reconnectAttemptsRef = useRef(0)
|
||||
const mountedRef = useRef(true)
|
||||
const socketRef = useRef<WebSocket | null>(null)
|
||||
// 콜백을 ref로 유지 — connect 클로저가 재생성되지 않아도 최신 콜백 참조
|
||||
const onMarketUpdateRef = useRef(options?.onMarketUpdate)
|
||||
const onChartDataRef = useRef(options?.onChartData)
|
||||
const baseDelay = 3000
|
||||
|
||||
// options 변경 시 ref 동기화
|
||||
useEffect(() => {
|
||||
onMarketUpdateRef.current = options?.onMarketUpdate
|
||||
onChartDataRef.current = options?.onChartData
|
||||
})
|
||||
|
||||
const connect = useCallback(() => {
|
||||
if (!mountedRef.current) return
|
||||
|
||||
@@ -39,6 +55,19 @@ export const useWebSocket = (clientId: string) => {
|
||||
try {
|
||||
const message = JSON.parse(event.data) as WebSocketMessage
|
||||
if (message.type === 'pong') return
|
||||
|
||||
// market_update: 콜백으로만 전달 (배열 누적 방지 — 틱마다 수신)
|
||||
if (message.type === 'market_update') {
|
||||
onMarketUpdateRef.current?.(message.data)
|
||||
return
|
||||
}
|
||||
|
||||
// chart_data: 콜백으로만 전달 (배열 누적 방지 — 차트 로드 전용)
|
||||
if (message.type === 'chart_data') {
|
||||
onChartDataRef.current?.(message)
|
||||
return
|
||||
}
|
||||
|
||||
setMessages((prev: WebSocketMessage[]) => [...prev, message])
|
||||
} catch (error) {
|
||||
console.error('Failed to parse WebSocket message:', error)
|
||||
@@ -52,7 +81,7 @@ export const useWebSocket = (clientId: string) => {
|
||||
ws.onclose = () => {
|
||||
console.log('🔌 WebSocket disconnected')
|
||||
setConnected(false)
|
||||
setSocket(null)
|
||||
socketRef.current = null
|
||||
|
||||
if (pingIntervalRef.current) {
|
||||
clearInterval(pingIntervalRef.current)
|
||||
@@ -71,7 +100,7 @@ export const useWebSocket = (clientId: string) => {
|
||||
}
|
||||
}
|
||||
|
||||
setSocket(ws)
|
||||
socketRef.current = ws
|
||||
} catch (error) {
|
||||
console.error('Failed to create WebSocket:', error)
|
||||
}
|
||||
@@ -89,17 +118,17 @@ export const useWebSocket = (clientId: string) => {
|
||||
if (pingIntervalRef.current) {
|
||||
clearInterval(pingIntervalRef.current)
|
||||
}
|
||||
if (socket) {
|
||||
socket.close()
|
||||
if (socketRef.current) {
|
||||
socketRef.current.close()
|
||||
}
|
||||
}
|
||||
}, [connect])
|
||||
|
||||
const sendMessage = useCallback((message: string) => {
|
||||
if (socket && connected) {
|
||||
socket.send(message)
|
||||
if (socketRef.current && socketRef.current.readyState === WebSocket.OPEN) {
|
||||
socketRef.current.send(message)
|
||||
}
|
||||
}, [socket, connected])
|
||||
}, [])
|
||||
|
||||
return { messages, connected, sendMessage }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user