live / dashboard /hooks /useWebSocket.ts
ayush77uh's picture
Add complete dashboard with WebSocket API, stream health monitoring, and scene controls
d1290e2
Raw
History Blame Contribute Delete
2.47 kB
'use client'
import { useState, useEffect, useRef, useCallback } from 'react'
interface StreamState {
is_running: boolean
status: string
current_video: {
name: string
id: string
started_at: string
} | null
videos_queue: Array<{ id: string; name: string }>
videos_played: number
session_start: string | null
session_end: string | null
total_stream_time: number
metrics: {
bitrate: number
fps: number
frame: number
time: string
speed: string
connection_status: string
}
scene: {
brb_active: boolean
logo_active: boolean
overlay_text: string
}
}
export default function useWebSocket(url: string) {
const [state, setState] = useState<StreamState | null>(null)
const [connected, setConnected] = useState(false)
const wsRef = useRef<WebSocket | null>(null)
const reconnectTimeoutRef = useRef<NodeJS.Timeout>()
const connect = useCallback(() => {
try {
const ws = new WebSocket(url)
wsRef.current = ws
ws.onopen = () => {
console.log('WebSocket connected')
setConnected(true)
// Request initial state
ws.send(JSON.stringify({ action: 'get_state' }))
}
ws.onmessage = (event) => {
try {
const data = JSON.parse(event.data)
setState(data)
} catch (err) {
console.error('Failed to parse WebSocket message:', err)
}
}
ws.onclose = () => {
console.log('WebSocket disconnected')
setConnected(false)
wsRef.current = null
// Auto-reconnect after 3 seconds
reconnectTimeoutRef.current = setTimeout(() => {
console.log('Attempting to reconnect...')
connect()
}, 3000)
}
ws.onerror = (error) => {
console.error('WebSocket error:', error)
}
} catch (err) {
console.error('Failed to connect WebSocket:', err)
}
}, [url])
const sendMessage = useCallback((message: object) => {
if (wsRef.current?.readyState === WebSocket.OPEN) {
wsRef.current.send(JSON.stringify(message))
} else {
console.warn('WebSocket not connected')
}
}, [])
useEffect(() => {
connect()
return () => {
if (reconnectTimeoutRef.current) {
clearTimeout(reconnectTimeoutRef.current)
}
if (wsRef.current) {
wsRef.current.close()
}
}
}, [connect])
return { state, connected, sendMessage }
}