useWebSocket.ts 1.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. import { useEffect, useRef, useState } from "react";
  2. interface UseWebSocketOptions {
  3. onMessage?: (data: unknown) => void;
  4. onError?: (error: Event) => void;
  5. onClose?: () => void;
  6. }
  7. export const useWebSocket = (traceId: string | null, options: UseWebSocketOptions = {}) => {
  8. const wsRef = useRef<WebSocket | null>(null);
  9. const [connected, setConnected] = useState(false);
  10. const { onMessage, onError, onClose } = options;
  11. useEffect(() => {
  12. if (!traceId) return;
  13. const url = `ws://localhost:8000/api/traces/${traceId}/watch?since_event_id=0`;
  14. const ws = new WebSocket(url);
  15. ws.onopen = () => {
  16. setConnected(true);
  17. };
  18. ws.onmessage = (event) => {
  19. try {
  20. const data = JSON.parse(event.data);
  21. onMessage?.(data);
  22. } catch {
  23. onMessage?.(event.data);
  24. }
  25. };
  26. ws.onerror = (error) => {
  27. onError?.(error);
  28. };
  29. ws.onclose = () => {
  30. setConnected(false);
  31. onClose?.();
  32. };
  33. wsRef.current = ws;
  34. return () => {
  35. ws.close();
  36. };
  37. }, [traceId, onMessage, onError, onClose]);
  38. return { connected, ws: wsRef.current };
  39. };