このページの目次
WebRTC
ブラウザ間での直接な音声・動画の転送——WebRTC は SDP でメディアパラメータを交渉し、ICE で NAT トンネリングを行い、DTLS-SRTP で暗号化転送を行います。P2P の「サーバーを経由しない」ことはパフォーマンス上の利点であると同時に、デバッグの悪夢でもあります。
概要
WebRTC(2011年)はブラウザに組み込まれたリアルタイム通信の標準規格であり、プラグインなしでビデオ通話、画面共有、P2P データ転送を実現します。複数のプロトコルを組み合わせており、SDP がメディアの交渉、ICE が NAT 穿透、DTLS-SRTP がメディアの暗号化、SCTP がデータチャネルを担当します。WebRTC の接続確立は非同期で行われ、candidate が一つずつ到着し検証されます。Trickle ICE を使用することで、接続時間を大幅に短縮できます。
アーキテクチャスタック
シグナリング: 意図的に空白とされた一环
WebRTC はシグナリングを規定していません——両端が SDP と ICE candidate をどのように交換するかは標準では一切規定されず、WebSocket/HTTP/任意のチャネルを使って自分で実装する必要があります。これは意図的な設計です。メディアパスは P2P である必要がありますが、「まだ接続していない2人がどのように最初に接触するか」は、双方が到達可能なサードパーティを必要とします。
まずシグナリングによって offer/answer を渡す必要があり、そうして初めて ICE が接続可能な candidate を持つことができる——これが WebRTC の「鶏が先か卵が先か」の問題である。
SDP 交渉
Caller → Callee (Offer):
v=0
o=- 1234567890 2 IN IP4 192.168.1.100
s=-
t=0 0
a=group:BUNDLE audio video data ← 同一の転送パス上でマルチプレクス
m=audio 49170 UDP/TLS/RTP/SAVPF 111 103
c=IN IP4 192.168.1.100
a=rtpmap:111 opus/48000/2
a=rtcp-mux ← RTP と RTCP は同一ポート
a=ice-ufrag:8sdf7g
a=ice-pwd:asd88fg
a=fingerprint:sha-256 AB:CD:... ← DTLS 証明書ハッシュ
Callee → Caller (Answer):
m=audio 49180 UDP/TLS/RTP/SAVPF 111 ← 選択されたポート + コーデック
...
→ 双方の交渉完了 → ICE 接続チェック開始
ICE
各ピアは3種類の candidate を収集する:
- host: ローカル IP:port
- srflx (server reflexive): STUN サーバーから返されるパブリック IP:port
- relay (relayed): TURN サーバーが割り当てる中継アドレス
各 (ローカル candidate + リモート candidate) のペアに対して接続チェック (STUN binding) を実行し → 最適な利用可能なペアを選択する(優先度は host > srflx > relay、つまり「直結可能なら中継を使わない」)。
STUN と TURN の役割分担: STUN は単に「自分のパブリックマッピングを問い合わせてくれる」だけで、メディアを転送せず、ほぼコストゼロです。しかし、両端が対称型 NAT の背後にあり、ホールパンチングに失敗した場合、TURN 中継に退避する必要があります——すべてのメディアがそれを介して転送され、帯域幅のコストが高くなります。これがデプロイにおいて唯一避けられないサーバーコストです。本番環境での経験則では、約 10〜20% の接続が最終的に TURN に落ちます。
Trickle ICE: すべての candidate の収集が完了するのを待ってから offer を送信する必要はありません。candidate は発見次第シグナリングを通じて相手側に送信され、接続チェックが行われます。これにより、接続確立時間を「最も遅い candidate を待つ」状態から「最初の利用可能なペアが準備できるまで」に圧縮します——これが WebRTC の高速な接続確立の鍵です。
DTLS-SRTP
DTLS ハンドシェイク (UDP 上の TLS 1.2 に類似) → ハンドシェイク完了後、双方は DTLS から SRTP 鍵を派生します(追加の交換は不要):
Data Channel
DTLS 上に覆いかぶさる SCTP (Stream Control Transmission Protocol):
TCP との比較:
- 複数ストリーム (HOL blocking が発生しない)
- メッセージ境界を保持
- 設定可能: 信頼性あり (reliable) / 部分的信頼性 (timed reliability)
適した用途: ファイル転送、ゲームステート、チャット
輻輳制御と Simulcast
リアルタイムメディアは TCP のようにパケット損失と再送に依存できません——1フレームのタイムリミットはわずか十数ミリ秒であり、再送を待っていると確実にタイムアウトします。WebRTC は GCC (Google Congestion Control) を使用します: RTP パケットの到着に基づくレイテンシー勾配で輻輳を予測し(キューが増加中 → 早めにレート降下)、実際にパケットが損失する前に検知し、送信側はこれに基づいてエンコーディングレートを動的に調整します。
Simulcast / SVC は、マルチユーザー会議における異種帯域幅の問題を解決します: 1つのカメラ入力から同時に複数の品質レベル(例: 180p/360p/720p)をエンコードし、中間サーバーが各受信者のネットワーク状況に応じて適切なレベルを選択して配信します——これが、以下の SFU が「ユーザーごとにレベルを選択できる」前提条件です。
SFU / MCU / Mesh — マルチユーザートポロジ
WebRTC は本来 P2P ですが、マルチユーザーの場合、P2P はスケーラビリティに欠けるため、サーバーの導入が必須です。3つのトポロジ(ストリーミングプロトコルにおける配信のトレードオフと同根):
なぜ WebRTC が HLS のように CDN で展開しにくいのか: 各接続には状態がある(ICE/DTLS/SRTP のコンテキスト + リアルタイムの輻輳フィードバック)ため、キャッシュ可能なファイルではありません。大規模展開はエッジキャッシュではなく、SFU のカスケードによってのみ可能——これが「サブ秒のリアルタイム性」がもたらす根本的な代償です。
参考
- webrtc.org: webrtc.googlesource.com
- ツール:
chrome://webrtc-internals
Keywords: WebRTC, signaling, SDP, ICE, Trickle ICE, STUN, TURN, DTLS-SRTP, SCTP, Data Channel, GCC, simulcast, SVC, SFU, MCU, mesh, Opus