Die OpenAI Realtime API verbindet Clients über WebSocket oder WebRTC. Für serverseitige Verbindungen kannst du OpenAI von jeder Maschine mit Internet direkt erreichen. Für clientseitige Verbindungen – also das meiste, was du damit tatsächlich bauen willst – braucht der Browser einen sicheren Origin und dein Backend muss ephemere Tokens ausstellen. Beides funktioniert über einen Tunnel. Ein paar Details solltest du kennen.
Zwei Verbindungsarten, zwei Gründe zu tunneln
Die Realtime API unterstützt serverseitige Verbindungen (dein Backend öffnet einen WebSocket zu OpenAI) und clientseitige Verbindungen (ein Browser öffnet eine WebRTC-Peer-Verbindung oder einen WebSocket mit einem ephemeren Token, das dein Backend ausstellt). Der serverseitige Weg braucht keinen Tunnel. Der clientseitige fast immer schon.
Warum die Client-Seite HTTPS braucht:
- Browser-Mikrofonberechtigungen erfordern einen sicheren Origin.
- WebRTCs
getUserMediaund ICE-Handling funktionieren am besten über HTTPS. - Service Worker (falls du welche hast) brauchen es.
- Wenn du den
/session-Endpunkt deines Backends aufrufst, um ein ephemeres Token zu bekommen, muss dieses Backend ebenfalls HTTPS sein, wenn dein Frontend es ist.
Den ersten Punkt kannst du mit Browser-Flags umgehen. Lass es. Nimm einen Tunnel und lebe in der echten Welt.
Die Struktur einer Realtime-App in der Entwicklung
Eine minimale Realtime-App hat drei Teile:
- Ein Frontend, das Mikrofoneingabe erfasst und Audioausgabe rendert.
- Eine Backend-Route, die ein ephemeres Token ausstellt, indem sie OpenAIs
/v1/realtime/sessions-Endpunkt mit deinem echten API-Key aufruft. - Eine direkte WebRTC- oder WebSocket-Verbindung vom Browser zu OpenAI mit dem ephemeren Token.
Dein Tunnel macht das Frontend + Backend zugänglich (in den meisten Setups dieselbe Domain). Der eigentliche Realtime-Traffic läuft Browser-zu-OpenAI, nicht durch deinen Tunnel – diese Verbindung ist direkt über HTTPS/WSS.
Schnelles Setup mit PortPreview
- Starte deinen Dev-Server (Next.js, Vite, was auch immer) auf Port 3000 oder 5173.
- Führe
npx portpreview 3000aus. - Öffne die HTTPS-URL in einem Browser. Mikrofon-Berechtigungsdialoge funktionieren normal.
- Rufe deinen Token-Ausstell-Endpunkt auf, hole ein ephemeres Token, öffne die Realtime-Verbindung.
- Sprich, erhalte eine gestreamte Antwort.
Wenn du Vite nutzt, brauchst du die allowedHosts- und HMR-Config aus Vite + Tunnel. Bei Next.js mit Edge-Runtime irgendwo: achte auf die Runtime-Config bei Routen, die Node-Crypto brauchen.
WebSocket-Upgrades durch Tunnel
Realtime-Verbindungen sind WebSocket (oder WebRTC, das den Tunnel meist umgeht). Jeder Tunnel, den du nutzt, muss den HTTP-Upgrade-Request korrekt weiterleiten. Die meisten tun das – PortPreview, Cloudflare-Quick-Tunnels, ngrok handhaben alle WebSocket-Upgrades. Tut es deiner nicht, scheitert die Verbindung im Browser still mit einer generischen WebSocket closed before connected-Meldung und ohne nützliches Detail.
Teste das Upgrade mit wscat, wenn du unsicher bist. Verbinde dich mit wss://your-tunnel.portpreview.dev/anything und beobachte den Handshake.
Die Dev-Tricks, die helfen
Den Token-Ausstell-Request inspizieren
Dein Frontend ruft eine Backend-Route auf, die OpenAI aufruft. Der häufigste Dev-Bug hier ist ein falsch konfigurierter Request an /v1/realtime/sessions – falscher Modellname, falsche Voice, falsche Modalities. Dein Tunnel erfasst den Request von Frontend zu Backend, aber nicht den Backend-zu-OpenAI-Hop. Logge diesen Request serverseitig, oder proxye ihn durch deinen Tunnel, indem du beide Schichten lokal laufen lässt.
Audio-Format-Mismatches
Die Realtime API nutzt standardmäßig PCM16 mit konfigurierbarer Sample-Rate. Wenn du Audio aus einem anderen Format einspeist, wird das Modell entweder ablehnen oder halluzinieren. Browser-MediaRecorder liefert meist Opus oder WebM – du musst die Konvertierung handhaben oder den WebRTC-Weg nutzen, der es für dich erledigt.
Token-Ablauf bei langen Sitzungen
Ephemere Tokens sind kurzlebig. Wenn du eine Sitzung testest, die länger als die Token-TTL ist, erneuere planmäßig. Das Realtime-SDK hat Helfer dafür; eigenes Rollen heißt, auf das session.expired-Event zu achten und ein neues Token auszustellen, bevor das alte stirbt.
Wie das in Produktion aussieht
Die einzige echte Änderung von Dev zu Prod ist die URL: ersetze den Tunnel-Hostnamen durch deine echte Domain. Der Token-Ausstell-Endpunkt bleibt auf deinem Backend. Die WebRTC/WebSocket-Verbindung vom Browser zu OpenAI ist derselbe Code-Pfad. Wir haben Teams gesehen, die das überdenken und versuchen, Realtime-Traffic durch ihr Backend zu proxen – lass es, das fügt Latenz hinzu und bricht das Modell, das OpenAIs SDK annimmt.
Für Anthropics paralleles Angebot (das eher einer Tool-Use-Schleife als einem Streaming-WebSocket gleicht) siehe Anthropic Tool Use und Webhooks lokal. Tritt der PortPreview-Warteliste bei für einen Tunnel, der WebSocket-Upgrades standardmäßig handhabt.