({ children })
| 36 | } |
| 37 | |
| 38 | export const WebsocketProvider = ({ children }) => { |
| 39 | const [isReady, setIsReady] = useState(false); |
| 40 | const [val, setVal] = useState(null); |
| 41 | const ws = useRef(null); |
| 42 | const reconnectTimerRef = useRef(null); |
| 43 | const [reconnectAttempts, setReconnectAttempts] = useState(0); |
| 44 | const [connectionError, setConnectionError] = useState(null); |
| 45 | const maxReconnectAttempts = 5; |
| 46 | const initialBackoffDelay = 1000; // 1 second initial delay |
| 47 | const env_mode = useSettingsStore((s) => s.environment.env_mode); |
| 48 | const accessToken = useAuthStore((s) => s.accessToken); |
| 49 | const isAuthenticated = useAuthStore((s) => s.isAuthenticated); |
| 50 | |
| 51 | const epgs = useEPGsStore((s) => s.epgs); |
| 52 | const updateEPG = useEPGsStore((s) => s.updateEPG); |
| 53 | |
| 54 | const updatePlaylist = usePlaylistsStore((s) => s.updatePlaylist); |
| 55 | |
| 56 | // Calculate reconnection delay with exponential backoff |
| 57 | const getReconnectDelay = useCallback(() => { |
| 58 | return Math.min( |
| 59 | initialBackoffDelay * Math.pow(1.5, reconnectAttempts), |
| 60 | 30000 |
| 61 | ); // max 30 seconds |
| 62 | }, [reconnectAttempts]); |
| 63 | |
| 64 | // Clear any existing reconnect timers |
| 65 | const clearReconnectTimer = useCallback(() => { |
| 66 | if (reconnectTimerRef.current) { |
| 67 | clearTimeout(reconnectTimerRef.current); |
| 68 | reconnectTimerRef.current = null; |
| 69 | } |
| 70 | }, []); |
| 71 | |
| 72 | // Function to get WebSocket URL that works with both HTTP and HTTPS |
| 73 | const getWebSocketUrl = useCallback(() => { |
| 74 | const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'; |
| 75 | const host = window.location.hostname; |
| 76 | const appPort = window.location.port; |
| 77 | |
| 78 | // In development mode, connect directly to the WebSocket server on port 8001 |
| 79 | if (env_mode === 'dev') { |
| 80 | return `${protocol}//${host}:8001/ws/?token=${accessToken}`; |
| 81 | } else { |
| 82 | // In production mode, use the same port as the main application |
| 83 | // This allows nginx to handle the WebSocket forwarding |
| 84 | return appPort |
| 85 | ? `${protocol}//${host}:${appPort}/ws/?token=${accessToken}` |
| 86 | : `${protocol}//${host}/ws/?token=${accessToken}`; |
| 87 | } |
| 88 | }, [env_mode, accessToken]); |
| 89 | |
| 90 | // Function to handle websocket connection |
| 91 | const connectWebSocket = useCallback(() => { |
| 92 | // Clear any existing timers to avoid multiple reconnection attempts |
| 93 | clearReconnectTimer(); |
| 94 | |
| 95 | // Clear old websocket if exists |
nothing calls this directly
no test coverage detected