File size: 1,888 Bytes
a0fcd39 | 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 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | import { useState, useEffect, useRef, useCallback } from 'react'
export function useWebSocket(sessionId) {
const [messages, setMessages] = useState([])
const [isConnected, setIsConnected] = useState(false)
const wsRef = useRef(null)
const reconnectTimeoutRef = useRef(null)
const connect = useCallback(() => {
if (!sessionId) return
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'
const wsUrl = `${protocol}//${window.location.host}/api/ws/${sessionId}`
try {
wsRef.current = new WebSocket(wsUrl)
wsRef.current.onopen = () => {
setIsConnected(true)
console.log('WebSocket connected')
}
wsRef.current.onmessage = (event) => {
try {
const data = JSON.parse(event.data)
setMessages(prev => [...prev, data])
} catch (e) {
console.error('Failed to parse WebSocket message:', e)
}
}
wsRef.current.onclose = () => {
setIsConnected(false)
console.log('WebSocket disconnected')
// Attempt to reconnect after 3 seconds
reconnectTimeoutRef.current = setTimeout(() => {
connect()
}, 3000)
}
wsRef.current.onerror = (error) => {
console.error('WebSocket error:', error)
}
} catch (e) {
console.error('Failed to create WebSocket:', e)
}
}, [sessionId])
const disconnect = useCallback(() => {
if (reconnectTimeoutRef.current) {
clearTimeout(reconnectTimeoutRef.current)
}
if (wsRef.current) {
wsRef.current.close()
}
}, [])
useEffect(() => {
if (sessionId) {
connect()
}
return () => {
disconnect()
}
}, [sessionId, connect, disconnect])
const clearMessages = useCallback(() => {
setMessages([])
}, [])
return {
messages,
isConnected,
clearMessages
}
}
|