Bedrud Dokumentation

Wie Clients in Bedrud Echtzeit-Medienverbindungen herstellen. Behandelt den vollständigen Verbindungs-Stack: Signalisierung, ICE, STUN, TURN und den SFU-Medienpfad.


Übersicht

WebRTC erfordert eine Reihe von Schritten, bevor Audio und Video zwischen Client und Server fließen. Bedrud verwendet die SFU-Architektur (Selective Forwarding Unit) von LiveKit - Clients verbinden sich mit dem Server, nicht miteinander. Das bedeutet, dass nur der Client-zu-Server-Netzwerkpfad relevant ist, nicht die Verbindung zwischen einzelnen Teilnehmern.

sequenceDiagram
    participant C as Client
    participant S as Bedrud Server
    participant LK as LiveKit SFU
 
    C->>S: POST /api/room/join
    S->>S: Validate permissions
    S->>C: LiveKit JWT token
 
    C->>LK: WebSocket connect (with token)
    LK->>C: Join response + SDP offer
 
    Note over C,LK: ICE Candidate Gathering
    C->>LK: Host candidates (local IPs)
    C->>LK: STUN candidates (public IPs)
    C->>LK: TURN candidates (relay addresses)
 
    alt Direct path available
        Note over C,LK: ICE/UDP - direct media
        C-->>LK: Media via UDP 50000-60000
    else UDP blocked, TURN available
        Note over C,LK: TURN - relayed media
        C-->>LK: Media via TURN relay (3478/5349)
    else Corporate firewall
        Note over C,LK: TURN/TLS - relayed via 443
        C-->>LK: Media via TLS tunnel
    end
 
    Note over C,LK: Audio/video tracks flow through SFU

Verbindungs-Stack

Fünf Schichten arbeiten zusammen, um den Medienpfad herzustellen:

flowchart TB
    subgraph Layers["Connectivity Stack"]
        direction TB
        SIG["1. Signaling<br/>WebSocket - exchange SDP offers/answers"]
        ICE["2. ICE<br/>Orchestrate all candidate paths"]
        STUN["3. STUN<br/>Discover public IP/port"]
        TURN["4. TURN<br/>Relay when direct fails"]
        SFU["5. SFU<br/>Route media between participants"]
    end
 
    SIG --> ICE
    ICE --> STUN
    ICE --> TURN
    STUN --> SFU
    TURN --> SFU

Schichtdetails

1. Signalisierung - Client und Server tauschen Verbindungsmetadaten über SDP-Angebote und -Antworten (Session Description Protocol) über WebSocket aus. Dies ist keine Medienübertragung - es ist die Aufbauphase. Bedrud leitet die Signalisierung über den API-Server an die eingebettete LiveKit-Instanz weiter.

2. ICE (Interactive Connectivity Establishment) - Sammelt alle möglichen Verbindungspfade, sogenannte Kandidaten, und testet sie in Prioritätsreihenfolge. ICE ist ein Framework - es koordiniert die Verbindungsversuche, ist aber selbst kein Protokoll.

3. STUN (Session Traversal Utilities for NAT) - Leichtgewichtiges Protokoll. Der Client sendet eine Binding-Anfrage an den STUN-Server, der mit der öffentlichen IP und dem Port des Clients antwortet. Dieser „Server-Reflexive”-Kandidat wird dann auf direkte Konnektivität getestet. Funktioniert bei ca. 80 % der Verbindungen.

4. TURN (Traversal Using Relays around NAT) - Wenn die direkte Konnektivität fehlschlägt, weist TURN eine Relay-Adresse auf dem Server zu. Alle Medienpakete werden über dieses Relay weitergeleitet. Höchste Kosten - die Serverbandbreite skaliert mit der Anzahl der Relay-Benutzer. Siehe den TURN-Server-Leitfaden für ausführliche Informationen.

5. SFU (Selective Forwarding Unit) - Sobald der Transportpfad hergestellt ist, leitet die SFU von LiveKit Medien zwischen Teilnehmern weiter. Jeder Teilnehmer sendet einen Stream nach oben; die SFU leitet Kopien an andere Teilnehmer weiter. Dies ist kein Peer-to-Peer - der Server ist immer im Pfad.


ICE-Kandidatensammlung

flowchart TD
    START[Start ICE Gathering] --> HOST
    START --> SRFLX
    START --> TURN_C
    HOST["Host candidates<br/>Local interface IPs<br/>e.g. 192.168.1.5:50001"]
    SRFLX["STUN candidates (srflx)<br/>Public IP discovered via STUN<br/>e.g. 203.0.113.5:50001"]
    TURN_C["TURN candidates (relay)<br/>Relay address on server<br/>e.g. 203.0.113.10:30001"]
    HOST --> TEST
    SRFLX --> TEST
    TURN_C --> TEST
    TEST{Test candidate<br/>connectivity}
    TEST -->|"Host works"| CONNECTED[Connected via host]
    TEST -->|"srflx works"| CONNECTED2[Connected via STUN<br/>direct P2P]
    TEST -->|"Only relay works"| CONNECTED3[Connected via TURN relay]
    TEST -->|"None work"| FAIL[Connection failed]

ICE sammelt gleichzeitig drei Kandidatentypen:

TypQuellePrioritätFunktionsweise
hostLokale NetzwerkschnittstellenHöchsteDirekte IP vom Rechner. Funktioniert im LAN.
srflx (Server Reflexive)STUN-Server-AntwortMittelÖffentliche IP, ermittelt über STUN. Funktioniert bei den meisten NAT-Typen.
relayTURN-Server-ZuweisungNiedrigsteAdresse auf dem TURN-Server. Funktioniert immer. Höchste Kosten.

ICE testet alle Kandidaten und wählt das Paar mit der höchsten Priorität, das erfolgreich ist. Wenn srflx funktioniert, wird relay übersprungen.


NAT-Typen und Konnektivität

Unterschiedliche NAT-Typen beeinflussen, ob direkte Konnektivität funktioniert:

flowchart LR
    subgraph NAT1["Client A NAT"]
        direction TB
        F["Full Cone"]
        R["Restricted Cone"]
        PR["Port Restricted"]
        S["Symmetric"]
    end
 
    subgraph NAT2["Client B / Server NAT"]
        direction TB
        F2["Full Cone"]
        R2["Restricted Cone"]
        PR2["Port Restricted"]
        S2["Symmetric"]
    end
 
    F -->|"Direct"| F2
    R -->|"Direct"| R2
    PR -->|"Direct"| PR2
    S -->|"TURN required"| S2
    S -.->|"TURN required"| PR2
    PR -.->|"TURN required"| S2
 
 
NAT-TypBeschreibungDirektes P2PTURN erforderlich
Full ConeAlle Anfragen von derselben internen IP/Port werden auf dieselbe öffentliche IP/Port abgebildet. Jeder externe Host kann daran senden.JaNein
Restricted ConeGleiche Abbildung wie Full Cone, aber nur externe Hosts, die ein Paket erhalten haben, können zurücksenden.MeistensNein
Port Restricted ConeÄhnlich wie Restricted Cone, aber der NAT schränkt auch die externe Portnummer ein. Der häufigste Heimrouter-Typ.MeistensSelten
SymmetricUnterschiedliche öffentliche IP/Port-Abbildung pro Ziel. Die über STUN ermittelte Adresse kann nicht wiederverwendet werden.Nein (wenn beide symmetrisch)Ja

Wichtige Erkenntnis: Da der Server eine öffentliche IP und einen vorhersagbaren Portbereich hat, funktionieren die meisten NAT-Typen direkt. TURN wird hauptsächlich benötigt, wenn die Firewall des Clients ausgehendes UDP vollständig blockiert.


Konfigurationsübersicht

Welche Bedrud/LiveKit-Konfigurationsschlüssel die WebRTC-Konnektivität beeinflussen:

livekit.yaml-Schlüssel:

rtc:
  port_range_start: 50000       # UDP media port range start
  port_range_end: 60000         # UDP media port range end
  tcp_port: 7881                # ICE/TCP fallback port
  stun_servers:                 # External STUN servers (optional)
    - stun:stun.l.google.com:19302
  use_external_ip: true         # Advertise public IP in ICE candidates
 
turn:
  enabled: true                 # Enable embedded TURN
  domain: "turn.example.com"    # TURN domain (DNS must resolve)
  udp_port: 3478                # TURN/UDP + STUN port
  tls_port: 5349                # TURN/TLS port (or 443)
  cert_file: /path/to/turn.crt  # TLS cert for TURN/TLS
  key_file: /path/to/turn.key   # TLS key for TURN/TLS
  relay_range_start: 30000      # Relay port range start
  relay_range_end: 40000        # Relay port range end
  external_tls: false           # L4 LB terminates TLS

config.yaml-Schlüssel (Bedrud-Server):

server:
  port: 8090                    # API port (signaling proxied through this)
  enableTLS: true               # HTTPS for signaling
  domain: "meet.example.com"    # Public domain

Fehlerbehebung bei Konnektivitätsproblemen

SymptomPrüfung
Überhaupt keine Verbindung möglichrtc.use_external_ip: true? Firewall offen auf 443 + UDP-Bereich?
Verbindet, aber kein Audio/VideoUDP 50000-60000 blockiert? ICE-Kandidaten im Browser prüfen.
Langsame VerbindungTURN-Relay aktiv (Kandidaten prüfen). Erwartet bei Client hinter striktem NAT.
Scheitert in UnternehmensnetzwerkenTURN/TLS nicht konfiguriert. turn.tls_port: 443 mit gültigem Zertifikat setzen.
Funktioniert im LAN, nicht aus der FerneÖffentliche IP nicht angekündigt. rtc.use_external_ip: true setzen.

Für ausführliche TURN-Fehlerbehebung siehe den TURN-Server-Leitfaden.


Siehe auch