QUIC vs WebRTC: なぜQUICに戻ったのか?
WebRTCの複雑さに疲れQUICに移行した実践事例
QUICはGoogleが設計しHTTP/3の基盤となった転送プロトコルだ。TCPの3つの根本的な問題 — 遅い接続確立(2~3 RTT)、Head-of-Line Blocking(パケット1つ喪失時に全体待機)、IP変更時の接続切断 — をUDP上で解決した。
Noctiluca開発記 — なぜQUICに辿り着いたか
unstablerという開発者がGeekNewsに投稿した実践開発記。macOSが嫌いでLinuxデスクトップにこだわっていたが、iOS開発の比重が増え、自分でリモート制御ソフトを作ることに。
試行1:xrdp + ulalaca
オープンソースRDP実装のxrdpをmacOSに接続しようとした。VNCバックエンド + ScreenCaptureKitを組み合わせた「ulalaca」というプラグインを作ったが、実用レベルに達しなかった。GFX/RemoteFXコーデック対応がWindowsから消え、オーディオ/クリップボード同期の開発・デバッグ難度が極めて高かった。
試行2:WebRTC
ulalacaを放置して半年後、WebRTCで再挑戦。しかしWebRTCにも壁があった:
カスタマイズの壁:画面データをビデオソースにするためChromiumソースを修正してビルドを繰り返す必要
ポート固定不可:シグナリングサーバー + STUN/TURNが必要で、送出ポートの固定・再利用が不可能
SCTPの呪い:WebRTC DataChannelは内部でSCTPを使用 — ペイロードがMTUを超えるとビデオ・オーディオストリームにラグ発生
試行3:QUIC — ついに解決
また半年放置。カフェでぼーっとしている時にQUICを思い出した。macOS/iOSのNetwork.frameworkがQUIC実装を提供していたためプロトタイプはすぐ作れた — WebRTCの全問題が即座に解決。
HOL Blocking解決:QUICのストリームは独立。オーディオパケット1つが飛んでも、マウス入力やビデオフレームは流れ続ける。
単一UDPポート:シグナリング/STUN/TURNの複雑な構成不要。UDPポート1つ開けるだけ。WiFi AP切り替え時もConnection Migrationで接続維持。
コミュニティの反応 — Parsecとの比較
「Parsecでいいのでは?」という反応も。Parsecは優秀だがモニターサイズ一致が必要でモバイル(iPad)非対応。NoctilucaはParsecができない領域 — RemoteApp的な個別ウィンドウ表示、USBリダイレクション、Linux laptopからのiOS開発を目指す。
QUICがリモート制御に適している理由
| 問題 | WebRTC | QUIC |
|---|---|---|
| インフラ複雑度 | シグナリング+STUN+TURN | UDPポート1つ |
| カスタマイズ | Chromiumソース修正 | 標準ライブラリ使用 |
| HOL Blocking | SCTP DataChannelで発生 | ストリーム独立で解決 |
| ポート固定 | 不可 | 可能 |
| Connection Migration | 未対応 | 標準対応 |
| メディアコーデック | 内蔵(長所でもあり短所) | 自前実装(自由度高い) |
構造ダイアグラム
動作フロー
クライアントがサーバーのUDPポートにInitialパケット送信(TLS 1.3 ClientHello含む)
サーバーがHandshakeパケットで応答 — 暗号化ネゴシエーション + 接続確立が1-RTTで完了
再訪問時0-RTT: 前回のセッションキーで最初のパケットからデータ送信可能
独立ストリーム多重化: ビデオ・オーディオ・入力を別々のストリームで送信、1つが喪失しても他に影響なし
Connection IDベースの接続管理: WiFi → LTE切り替え時にIPが変わっても接続維持(Connection Migration)
内蔵フロー制御 + 輻輳制御でネットワーク状態に適応的な転送
メリット
- ✓ 0-RTT / 1-RTT接続確立(TCP+TLS比で1~2 RTT節約)
- ✓ Head-of-Line Blocking完全解決(ストリーム独立)
- ✓ Connection Migration(IP変更でも接続維持)
- ✓ UDPポート1つで全通信(WebRTCのような複雑なインフラ不要)
- ✓ TLS 1.3内蔵(別途暗号化レイヤー不要)
デメリット
- ✗ UDPベースのため一部ファイアウォール/ネットワークでブロックされる可能性
- ✗ 既存TCPミドルボックス(ファイアウォール、IDS)との互換性問題
- ✗ 実装複雑度が高い(独自再送、輻輳制御の実装が必要)
- ✗ WebRTCのようなメディアコーデック/エコー除去などは未内蔵(自前実装)
- ✗ UDP最適化されたNIC/カーネルでないとパフォーマンス低下の可能性