| '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) |
| |
| 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 |
| |
| |
| 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 } |
| } |
|
|