Wszystkie artykuły
OpenAIRealtime APIWebSocketAI

Testowanie OpenAI Realtime API lokalnie przez tunel

OpenAI Realtime API łączy klientów przez WebSocket lub WebRTC. Dla połączeń po stronie serwera możesz uderzyć do OpenAI bezpośrednio z dowolnej maszyny z internetem. Dla połączeń po stronie klienta — czyli większości tego, co faktycznie chcesz tym zbudować — przeglądarka potrzebuje bezpiecznego origin, a twój backend musi wystawiać tokeny efemeryczne. Oba działają przez tunel. Kilka szczegółów warto znać.

Dwa sposoby łączenia, dwa powody do tunelowania

Realtime API obsługuje połączenia po stronie serwera (twój backend otwiera WebSocket do OpenAI) i połączenia po stronie klienta (przeglądarka otwiera połączenie peer WebRTC lub WebSocket, używając tokena efemerycznego wystawionego przez twój backend). Ścieżka serwerowa nie potrzebuje tunelu. Klienta — prawie zawsze tak.

Dlaczego strona klienta potrzebuje HTTPS:

  • Uprawnienia mikrofonu przeglądarki wymagają bezpiecznego origin.
  • getUserMedia WebRTC i obsługa ICE działają najlepiej po HTTPS.
  • Service workery (jeśli jakieś masz) tego wymagają.
  • Jeśli wołasz endpoint /session swojego backendu po token efemeryczny, ten backend też musi być HTTPS, jeśli twój frontend jest.

Pierwszy punkt możesz obejść flagami przeglądarki. Nie rób tego. Użyj tunelu i żyj w prawdziwym świecie.

Kształt aplikacji Realtime w developmencie

Minimalna aplikacja realtime ma trzy części:

  1. Frontend, który przechwytuje wejście mikrofonu i odtwarza wyjście audio.
  2. Trasa backendu, która wystawia token efemeryczny, uderzając do endpointu OpenAI /v1/realtime/sessions twoim prawdziwym kluczem API.
  3. Bezpośrednie połączenie WebRTC lub WebSocket z przeglądarki do OpenAI, używając tokena efemerycznego.

Twój tunel udostępnia frontend + backend (w większości konfiguracji ta sama domena). Właściwy ruch realtime idzie przeglądarka-do-OpenAI, nie przez twój tunel — to połączenie jest bezpośrednie przez HTTPS/WSS.

Szybka konfiguracja z PortPreview

  1. Uruchom serwer deweloperski (Next.js, Vite, cokolwiek) na porcie 3000 lub 5173.
  2. Wykonaj npx portpreview 3000.
  3. Otwórz adres HTTPS w przeglądarce. Monity o uprawnienia mikrofonu działają normalnie.
  4. Uderz do swojego endpointu wystawiającego tokeny, pobierz token efemeryczny, otwórz połączenie realtime.
  5. Mów, otrzymaj odpowiedź strumieniowaną.

Jeśli używasz Vite, będziesz potrzebować konfiguracji allowedHosts i HMR z Vite + tunel. Jeśli jesteś na Next.js z edge runtime gdziekolwiek, uważaj na konfigurację runtime na trasach wymagających crypto Node.

Upgrade'y WebSocket przez tunele

Połączenia realtime to WebSocket (lub WebRTC, który w większości omija tunel). Każdy tunel, którego używasz, musi poprawnie przekazywać żądanie HTTP Upgrade. Większość to robi — PortPreview, quick tunnels Cloudflare, ngrok obsługują upgrade'y WebSocket. Jeśli twój nie, połączenie zawodzi cicho w przeglądarce z ogólnym WebSocket closed before connected bez użytecznych szczegółów.

Przetestuj upgrade za pomocą wscat, jeśli nie jesteś pewien. Połącz się z wss://your-tunnel.portpreview.dev/anything i obserwuj handshake.

Triki deweloperskie, które pomagają

Sprawdź żądanie wystawienia tokena

Twój frontend woła trasę backendu, która woła OpenAI. Najczęstszy tutaj bug deweloperski to źle skonfigurowane żądanie do /v1/realtime/sessions — zła nazwa modelu, zły voice, złe modalities. Twój tunel przechwytuje żądanie frontend-do-backendu, ale nie skok backend-do-OpenAI. Loguj to żądanie po stronie serwera albo proxuj przez tunel, uruchamiając obie warstwy lokalnie.

Niezgodności formatu audio

Realtime API używa domyślnie PCM16 z konfigurowalną częstotliwością próbkowania. Jeśli wprowadzasz audio z innego formatu, model albo je odrzuci, albo zacznie halucynować. MediaRecorder przeglądarki zwykle daje Opus lub WebM — musisz obsłużyć konwersję albo użyć ścieżki WebRTC, która robi to za ciebie.

Wygaśnięcie tokena podczas długich sesji

Tokeny efemeryczne są krótkotrwałe. Jeśli testujesz sesję dłuższą niż TTL tokena, odświeżaj według harmonogramu. SDK Realtime ma do tego pomocniki; robienie tego ręcznie oznacza pilnowanie zdarzenia session.expired i wystawianie nowego tokena, zanim stary umrze.

Jak to wygląda na produkcji

Jedyną realną zmianą z developmentu na produkcję jest adres: zastąp nazwę hosta tunelu swoją prawdziwą domeną. Endpoint wystawiający tokeny zostaje na twoim backendzie. Połączenie WebRTC/WebSocket z przeglądarki do OpenAI to ta sama ścieżka kodu. Widzieliśmy zespoły, które to przekombinowują i próbują proxować ruch realtime przez backend — nie rób tego, dodaje opóźnienie i łamie model, który zakłada SDK OpenAI.

Po równoległą ofertę Anthropic (bliższą pętli tool use niż strumieniowemu WebSocket) zobacz Anthropic tool use i webhooki lokalnie. Dołącz do listy oczekujących PortPreview, by mieć tunel obsługujący upgrade'y WebSocket domyślnie.

Najczęściej zadawane pytania

Czy mogę testować OpenAI Realtime API na localhost?
Połączenia po stronie serwera nie potrzebują tunelu. Połączenia po stronie klienta z przeglądarki potrzebują HTTPS dla uprawnień mikrofonu i endpointów tokenów efemerycznych. Użyj tunelu, by udostępnić serwer deweloperski przez HTTPS, potem połącz przeglądarkę bezpośrednio z OpenAI tokenem efemerycznym.
Czy mój tunel musi obsługiwać WebSockety dla Realtime API?
Jeśli używasz transportu WebSocket, tak — tunel musi przekazywać żądania upgrade HTTP. Większość nowoczesnych tuneli to robi, ale warto to przetestować z wscat, zanim zaczniesz ścigać widmowy bug połączenia. WebRTC omija tunel dla samego ruchu realtime.
Dlaczego potrzebuję tokenów efemerycznych do połączeń realtime z przeglądarki?
Umieszczenie pełnego klucza API w przeglądarce to katastrofa bezpieczeństwa. Twój backend wystawia krótkotrwały token efemeryczny ograniczony do jednej sesji realtime. Przeglądarka używa tego tokena, by połączyć się bezpośrednio z OpenAI, nigdy nie widząc twojego prawdziwego klucza API.