Spaces:
Sleeping
Sleeping
File size: 1,500 Bytes
a9df8b1 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | import { useEffect, useRef } from 'react'
import { useAppStore } from '@/store/appStore'
import type { WsEvent } from '@/store/appStore'
type RawWsMessage = {
type?: unknown
payload?: unknown
timestamp?: unknown
event?: unknown
data?: unknown
}
function normalizeWsMessage(raw: RawWsMessage): WsEvent | null {
const type = typeof raw.type === 'string'
? raw.type
: typeof raw.event === 'string'
? raw.event
: ''
if (!type) return null
return {
type,
payload: 'payload' in raw ? raw.payload : raw.data,
timestamp: typeof raw.timestamp === 'string' ? raw.timestamp : new Date().toISOString(),
}
}
export function useWebSocket() {
const wsRef = useRef<WebSocket | null>(null)
const pushWsEvent = useAppStore(s => s.pushWsEvent)
useEffect(() => {
if (import.meta.env.VITE_SKILLOS_DISABLE_WS === '1') {
return
}
const protocol = window.location.protocol === 'https:' ? 'wss' : 'ws'
const ws = new WebSocket(`${protocol}://${window.location.host}/ws`)
wsRef.current = ws
ws.onmessage = (e) => {
try {
const msg = normalizeWsMessage(JSON.parse(e.data))
if (msg) pushWsEvent(msg)
} catch {
// ignore
}
}
const ping = setInterval(() => {
if (ws.readyState === WebSocket.OPEN) {
ws.send(JSON.stringify({ type: 'ping' }))
}
}, 30_000)
return () => {
clearInterval(ping)
ws.close()
}
}, [pushWsEvent])
return wsRef
}
|