Files
3x-ui/frontend/src/hooks/useWebSocket.ts
T
MHSanaei 58b88800b4 fix(frontend): share one WebSocket connection across bridge and hooks
websocketBridge.ts and useWebSocket.ts each declared their own
module-scoped sharedClient plus an identical getSharedClient, so the
"shared" client was not shared between them: whenever a page using
useWebSocket (Clients/Inbounds) mounted alongside the always-mounted
bridge, the panel opened two sockets to /ws. The server then pushed every
traffic/stats/nodes/inbounds snapshot to both, doubling WebSocket bandwidth
and running two independent reconnect loops, and the hook's socket was never
disconnected on unmount.

Hoist a single getSharedWebSocketClient into api/websocket.ts and route both
the bridge and the hook through it, so exactly one connection is opened.
2026-07-15 05:15:56 +02:00

18 lines
564 B
TypeScript

import { useEffect } from 'react';
import { getSharedWebSocketClient } from '@/api/websocket';
type Handler = (payload: unknown) => void;
export function useWebSocket(handlers: Record<string, Handler>) {
useEffect(() => {
const client = getSharedWebSocketClient();
const entries = Object.entries(handlers);
for (const [event, fn] of entries) client.on(event, fn);
client.connect();
return () => {
for (const [event, fn] of entries) client.off(event, fn);
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
}