import { useCallback, useEffect, useRef, useState } from 'react'; import { useStorageState } from 'react-storage-hooks'; import { socketKeepaliveTimeout } from '../constants/system'; const url = 'ws://localhost:3002/pubsub'; // TODO export function useSocket(): { name: string | null; onIdentify: (name: string) => void; socket: WebSocket | null; error: boolean; connecting: boolean; connected: boolean; } { const [name, saveName] = useStorageState(localStorage, 'client-name', ''); const [socket, setSocket] = useState(null); const [error, setError] = useState(false); const [connecting, setConnecting] = useState(false); const onIdentify = useCallback( (newName: string) => { setConnecting(true); const ws = new WebSocket(`${url}?client-name=${name}`); ws.onopen = (): void => { if (ws.readyState === ws.OPEN) { setError(false); setConnecting(false); saveName(newName); setSocket(ws); } }; ws.onclose = (): void => { setError(false); setSocket(null); }; }, [saveName], ); return { name, onIdentify, socket, error, connecting, connected: socket?.readyState === socket?.OPEN, }; } export function useKeepalive(socket: WebSocket): void { const keepalive = useRef(); useEffect(() => { keepalive.current = window.setInterval(() => { if (socket.readyState === socket.OPEN) { socket.send(JSON.stringify({ type: 'PING' })); } else { socket.close(); } }, socketKeepaliveTimeout); return (): void => { clearInterval(keepalive.current); }; }, [socket]); }