Bedrud ドキュメント

Bedrud でクライアントがリアルタイムメディア接続を確立する仕組みについて説明します。シグナリング、ICE、STUN、TURN、SFU メディアパスの完全な接続スタックをカバーします。


概要

WebRTC では、クライアントとサーバー間で音声とビデオが流れる前に一連の手順が必要です。Bedrud は LiveKit の SFU(Selective Forwarding Unit)アーキテクチャを使用しています。クライアントは互いではなく、サーバーに接続します。つまり、個々の参加者間の接続ではなく、クライアントとサーバー間のネットワークパスのみが重要です。

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

接続スタック

メディアパスを確立するために、5つのレイヤーが連携して動作します。

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

各レイヤーの詳細

1. シグナリング - クライアントとサーバーは WebSocket 経由で SDP(Session Description Protocol)のオファーとアンサーを使って接続メタデータを交換します。これはメディアではなく、セットアップフェーズです。Bedrud は API サーバー経由でシグナリングをプロキシし、組み込みの LiveKit インスタンスに転送します。

2. ICE(Interactive Connectivity Establishment) - 候補(candidates)と呼ばれるすべての可能な接続パスを収集し、優先順位に従ってテストします。ICE はフレームワークであり、接続の試行を調整するものですが、プロトコルそのものではありません。

3. STUN(Session Traversal Utilities for NAT) - 軽量プロトコルです。クライアントが STUN サーバーにバインディングリクエストを送信すると、サーバーはクライアントのパブリック IP とポートで応答します。この「サーバーリフレクシブ」候補が直接接続のためにテストされます。約 80% の接続で機能します。

4. TURN(Traversal Using Relays around NAT) - 直接接続に失敗した場合、TURN はサーバー上にリレーアドレスを割り当てます。すべてのメディアパケットはこのリレーを通じて転送されます。コストが最も高く、サーバーの帯域幅はリレーするユーザーに比例して増加します。詳細は TURN サーバーガイド を参照してください。

5. SFU(Selective Forwarding Unit) - トランスポートパスが確立されると、LiveKit の SFU が参加者間でメディアをルーティングします。各参加者は一つのストリームを送信し、SFU がコピーを他の参加者に転送します。これはピアツーピアではなく、サーバーが常にパス上に存在します。


ICE 候補の収集

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 は3種類の候補タイプを同時に収集します。

タイプ送信元優先度動作
hostローカルネットワークインターフェース最高マシンからの直接 IP。LAN 内で機能します。
srflx(サーバーリフレクシブ)STUN サーバーの応答STUN 経由で発見されたパブリック IP。ほとんどの NAT タイプで機能します。
relayTURN サーバーの割り当て最低TURN サーバー上のアドレス。常に機能します。コストが最も高い。

ICE はすべての候補をテストし、成功した最も優先度の高いペアを選択します。srflx が機能する場合、relay はスキップされます。


NAT タイプと接続性

NAT タイプによって、直接接続が可能かどうかが変わります。

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 タイプ説明直接 P2PTURN 必要
Full Cone同じ内部 IP/ポートからのすべてのリクエストが同じパブリック IP/ポートにマッピングされます。任意の外部ホストから送信可能です。はいいいえ
Restricted ConeFull Cone と同じマッピングですが、パケットを受信した外部ホストのみが送信できます。通常いいえ
Port Restricted ConeRestricted Cone に似ていますが、NAT が外部ポート番号も制限します。最も一般的な家庭用ルータータイプです。通常まれ
Symmetric宛先ごとに異なるパブリック IP/ポートマッピング。STUN で発見されたアドレスは再利用できません。いいえ(両方が Symmetric の場合)はい

重要なポイント: サーバーはパブリック IP と予測可能なポート範囲を持っているため、ほとんどの NAT タイプで直接接続が機能します。TURN は主に、クライアントのファイアウォールが送信 UDP を完全にブロックしている場合に必要です。


設定の概要

Bedrud/LiveKit のどの設定キーが WebRTC 接続に影響するか:

livekit.yaml の設定キー:

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 の設定キー(Bedrud サーバー):

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

接続問題のデバッグ

症状確認項目
まったく接続できないrtc.use_external_ip: true?ファイアウォールで 443 + UDP 範囲が開放されている?
接続できるが音声/ビデオがないUDP 50000-60000 がブロックされている?ブラウザで ICE 候補を確認。
接続が遅いTURN リレーがアクティブ(候補を確認)。厳格な NAT の背後の場合は想定内。
企業ネットワークで失敗するTURN/TLS が未設定。turn.tls_port: 443 を有効な証明書で設定。
LAN では機能するがリモートで失敗するパブリック IP がアドバタイズされていない。rtc.use_external_ip: true を設定。

TURN の詳細なトラブルシューティングについては、TURN サーバーガイド を参照してください。


関連項目