api / frontend /websocket.ts
gary-boon
Deploy Visualisable.ai backend with API protection
c6c8587
raw
history blame
3.14 kB
import { useEffect, useRef, useState, useCallback } from 'react';
import { getLegacyWsUrl } from './config';
import { TraceData, WebSocketState } from './types';
export type { TraceData, WebSocketState } from './types';
// DEPRECATED: Use websocket-client.ts instead
export function useWebSocket(url?: string) {
const defaultUrl = url || getLegacyWsUrl();
const [state, setState] = useState<WebSocketState>({
isConnected: false,
lastMessage: null,
traces: [],
});
const ws = useRef<WebSocket | null>(null);
const reconnectTimeout = useRef<NodeJS.Timeout | null>(null);
const connect = useCallback(() => {
// Only run in browser environment
if (typeof window === 'undefined') {
return;
}
try {
ws.current = new WebSocket(defaultUrl);
ws.current.onopen = () => {
console.log('WebSocket connected to:', defaultUrl);
setState(prev => ({ ...prev, isConnected: true }));
// Clear any reconnection timeout
if (reconnectTimeout.current) {
clearTimeout(reconnectTimeout.current);
reconnectTimeout.current = null;
}
};
ws.current.onmessage = (event) => {
try {
const data = JSON.parse(event.data) as TraceData;
console.log('Received trace:', data.type);
setState(prev => ({
...prev,
lastMessage: data,
traces: [...prev.traces, data].slice(-100), // Keep last 100 traces
}));
} catch (error) {
console.error('Error parsing WebSocket message:', error);
}
};
ws.current.onerror = (error) => {
console.error('WebSocket error:', error);
};
ws.current.onclose = () => {
console.log('WebSocket disconnected');
setState(prev => ({ ...prev, isConnected: false }));
// Attempt to reconnect after 3 seconds
reconnectTimeout.current = setTimeout(() => {
console.log('Attempting to reconnect...');
connect();
}, 3000);
};
} catch (error) {
console.error('Failed to connect WebSocket:', error);
}
}, [url]);
const disconnect = useCallback(() => {
if (reconnectTimeout.current) {
clearTimeout(reconnectTimeout.current);
reconnectTimeout.current = null;
}
if (ws.current) {
ws.current.close();
ws.current = null;
}
}, []);
const sendMessage = useCallback((message: Record<string, unknown>) => {
if (ws.current && ws.current.readyState === WebSocket.OPEN) {
ws.current.send(JSON.stringify(message));
} else {
console.warn('WebSocket is not connected');
}
}, []);
const clearTraces = useCallback(() => {
setState(prev => ({ ...prev, traces: [], lastMessage: null }));
}, []);
useEffect(() => {
// Only run in browser environment
if (typeof window === 'undefined') {
return;
}
connect();
return () => disconnect();
}, [connect, disconnect]);
return {
...state,
sendMessage,
clearTraces,
reconnect: connect,
disconnect,
};
}