← back to Dw Boardroom Governance
frontend/src/hooks/useWebSocket.ts
56 lines
import { useState, useEffect, useRef } from 'react';
import type { WSEvent } from '../types';
export function useWebSocket() {
const [events, setEvents] = useState<WSEvent[]>([]);
const [connected, setConnected] = useState(false);
const wsRef = useRef<WebSocket | null>(null);
useEffect(() => {
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
const wsUrl = `${protocol}//${window.location.host}/ws`;
let cancelled = false;
let reconnectTimer: ReturnType<typeof setTimeout> | null = null;
function connect() {
if (cancelled) return;
const ws = new WebSocket(wsUrl);
wsRef.current = ws;
ws.onopen = () => {
if (!cancelled) setConnected(true);
};
ws.onmessage = (e) => {
try {
const event: WSEvent = JSON.parse(e.data);
setEvents(prev => [...prev.slice(-99), event]);
} catch {}
};
ws.onclose = () => {
if (cancelled) return;
setConnected(false);
reconnectTimer = setTimeout(connect, 3000);
};
ws.onerror = () => {
ws.close();
};
}
connect();
return () => {
cancelled = true;
if (reconnectTimer) clearTimeout(reconnectTimer);
if (wsRef.current) {
wsRef.current.onclose = null;
wsRef.current.close();
}
};
}, []);
return { events, connected };
}