- 37개 파일 IP → zioinfo.co.kr 치환 (소스/매뉴얼/설정/하네스) - Manager DrConsole/NetworkConsole/CsapConsole 빌드 + /var/www/manager/ 배포 - 테스트: Manager HTTP 200, ITSM 신규 API 7개 전체 200 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
72 lines
2.0 KiB
TypeScript
72 lines
2.0 KiB
TypeScript
import { useEffect, useRef, useState, useCallback } from 'react'
|
|
import * as SecureStore from 'expo-secure-store'
|
|
import { API_BASE } from '../constants/Config'
|
|
|
|
const WS_BASE = API_BASE.replace('https://', 'wss://').replace('http://', 'ws://')
|
|
|
|
export interface WSEvent {
|
|
event_type: string
|
|
data: Record<string, unknown>
|
|
timestamp: string
|
|
}
|
|
|
|
export function useWebSocket(channels: string[] = []) {
|
|
const [connected, setConnected] = useState(false)
|
|
const [lastEvent, setLastEvent] = useState<WSEvent | null>(null)
|
|
const [events, setEvents] = useState<WSEvent[]>([])
|
|
const ws = useRef<WebSocket | null>(null)
|
|
const retry = useRef<ReturnType<typeof setTimeout> | null>(null)
|
|
|
|
const connect = useCallback(async () => {
|
|
const token = await SecureStore.getItemAsync('grd_token')
|
|
if (!token) return
|
|
|
|
const url = `${WS_BASE}/ws/events?token=${token}`
|
|
try {
|
|
ws.current = new WebSocket(url)
|
|
|
|
ws.current.onopen = () => {
|
|
setConnected(true)
|
|
// 채널 구독 메시지 전송
|
|
if (channels.length > 0 && ws.current) {
|
|
ws.current.send(JSON.stringify({ subscribe: channels }))
|
|
}
|
|
}
|
|
|
|
ws.current.onmessage = (e) => {
|
|
try {
|
|
const evt: WSEvent = JSON.parse(e.data)
|
|
setLastEvent(evt)
|
|
setEvents(prev => [evt, ...prev].slice(0, 50)) // 최근 50개 유지
|
|
} catch {}
|
|
}
|
|
|
|
ws.current.onclose = () => {
|
|
setConnected(false)
|
|
// 5초 후 재연결
|
|
retry.current = setTimeout(connect, 5000)
|
|
}
|
|
|
|
ws.current.onerror = () => {
|
|
ws.current?.close()
|
|
}
|
|
} catch {}
|
|
}, [])
|
|
|
|
useEffect(() => {
|
|
connect()
|
|
return () => {
|
|
if (retry.current) clearTimeout(retry.current)
|
|
ws.current?.close()
|
|
}
|
|
}, [connect])
|
|
|
|
const send = useCallback((data: object) => {
|
|
if (ws.current?.readyState === WebSocket.OPEN) {
|
|
ws.current.send(JSON.stringify(data))
|
|
}
|
|
}, [])
|
|
|
|
return { connected, lastEvent, events, send }
|
|
}
|