feat(docker): añadir Dockerfile para contenerizar la aplicación
This commit is contained in:
79
src/hooks/useWebSocket.ts
Normal file
79
src/hooks/useWebSocket.ts
Normal file
@@ -0,0 +1,79 @@
|
||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
|
||||
export type WsStatus = 'connecting' | 'open' | 'closed' | 'error';
|
||||
|
||||
interface UseWebSocketOptions {
|
||||
url: string | null;
|
||||
enabled?: boolean;
|
||||
onMessage?: (data: string) => void;
|
||||
reconnect?: boolean;
|
||||
reconnectIntervalMs?: number;
|
||||
}
|
||||
|
||||
export function useWebSocket({
|
||||
url,
|
||||
enabled = true,
|
||||
onMessage,
|
||||
reconnect = true,
|
||||
reconnectIntervalMs = 3000,
|
||||
}: UseWebSocketOptions) {
|
||||
const [status, setStatus] = useState<WsStatus>('closed');
|
||||
const wsRef = useRef<WebSocket | null>(null);
|
||||
const onMessageRef = useRef(onMessage);
|
||||
onMessageRef.current = onMessage;
|
||||
|
||||
const send = useCallback((data: string) => {
|
||||
if (wsRef.current?.readyState === WebSocket.OPEN) {
|
||||
wsRef.current.send(data);
|
||||
}
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (!enabled || !url) {
|
||||
setStatus('closed');
|
||||
return;
|
||||
}
|
||||
|
||||
let disposed = false;
|
||||
let reconnectTimer: ReturnType<typeof setTimeout> | undefined;
|
||||
|
||||
const connect = () => {
|
||||
if (disposed) return;
|
||||
setStatus('connecting');
|
||||
const ws = new WebSocket(url);
|
||||
wsRef.current = ws;
|
||||
|
||||
ws.onopen = () => {
|
||||
if (!disposed) setStatus('open');
|
||||
};
|
||||
|
||||
ws.onmessage = (event) => {
|
||||
onMessageRef.current?.(String(event.data));
|
||||
};
|
||||
|
||||
ws.onerror = () => {
|
||||
if (!disposed) setStatus('error');
|
||||
};
|
||||
|
||||
ws.onclose = () => {
|
||||
if (!disposed) {
|
||||
setStatus('closed');
|
||||
if (reconnect) {
|
||||
reconnectTimer = setTimeout(connect, reconnectIntervalMs);
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
connect();
|
||||
|
||||
return () => {
|
||||
disposed = true;
|
||||
if (reconnectTimer) clearTimeout(reconnectTimer);
|
||||
wsRef.current?.close();
|
||||
wsRef.current = null;
|
||||
};
|
||||
}, [url, enabled, reconnect, reconnectIntervalMs]);
|
||||
|
||||
return { status, send };
|
||||
}
|
||||
Reference in New Issue
Block a user