WebTransportガイド:ストリーム、データグラム、HTTP/3、使いどころ
WebTransportは、HTTP/3上でブラウザとサーバーが双方向通信するためのWeb APIです。1つの接続の中で、信頼性のあるストリームと、信頼性を保証しないデータグラムを使えます。
低遅延アプリには有用ですが、WebSocketやWebRTCを何でも置き換えるものではありません。使うべきかどうかは、アプリがどんなデータを流すのかから判断するのが現実的です。
WebTransportとは
WebTransportは、ブラウザがHTTP/3サーバーに接続し、次の2種類の方法でデータを交換できるようにします。
- 信頼性のあるストリーム:正しく到達する必要があるデータ向けの、順序付きバイトストリーム。
- 信頼性を保証しないデータグラム:低遅延を優先し、損失を許容できるデータ向けのメッセージ。
安全なコンテキストで使うAPIなので、実運用ではHTTPSが必要だと考えてください。また、ブラウザ、サーバー、ネットワーク経路、CDN、プロキシがHTTP/3を扱えることも重要です。
参考ドキュメント:
基本モデル
WebTransport接続は、複数の独立したチャネルを運べる1つのセッションとして考えると分かりやすいです。
ブラウザ
WebTransportセッション
信頼性のあるストリーム:チャット、ファイル断片、制御コマンド
信頼性のあるストリーム:別の独立した処理
データグラム:プレイヤー位置、センサー更新、リアルタイムカーソル
HTTP/3サーバー
重要なのは、データの種類ごとに配送ルールを変えられることです。決済確認をゲームの位置更新のように送るべきではありません。逆に、ゲームの位置更新が大きなファイル転送の後ろで待つのもよくありません。
ストリームとデータグラム
| 特性 | ストリーム | データグラム |
|---|---|---|
| 配送 | 信頼性あり | ベストエフォート |
| 順序 | 1つのストリーム内で順序あり | 保証されない |
| 向いているもの | ファイル、命令、チャット、取引 | ゲーム状態、テレメトリ、リアルタイムカーソル |
| 損失への対応 | トランスポートが信頼性を扱う | アプリが損失を許容する必要がある |
| データの形 | バイト列 | 独立したメッセージ |
正しさが重要ならストリームを使います。古い値より最新値が重要ならデータグラムを使います。
WebTransportとWebSocket
多くのアプリでは、WebSocketのほうがまだ簡単な選択です。広く使われていて、プロキシしやすく、エコシステムも成熟しています。
WebTransportが有力になるのは、次のような場合です。
- 1つのセッションで複数の独立ストリームが必要。
- 低遅延で、損失を許容できるメッセージが必要。
- 無関係なデータの間でヘッドオブラインブロッキングを減らしたい。
- HTTP/3ベースの新しいクライアント-サーバートランスポートを使いたい。
WebSocketが向く場合:
- 必要なのは1本の信頼できる順序付きメッセージストリームだけ。
- 既存インフラとの互換性を最大化したい。
- サーバー、CDN、社内ネットワークがHTTP/3を安定して扱えない。
- 運用をできるだけ単純にしたい。
WebTransportが新しいからという理由だけで、動いているWebSocketアプリを移行しないでください。ストリーム、データグラム、HTTP/3の性質が実際に効くときだけ検討します。
WebTransportとWebRTC Data Channel
WebRTC Data Channelは、ピアツーピアやメディア中心のリアルタイムシステムに向いています。WebTransportはクライアント-サーバーです。
WebRTCが向く場合:
- ブラウザ同士が直接通信する必要がある。
- アプリがすでに音声や映像のネゴシエーションを含んでいる。
- NAT越えをWebRTC基盤に任せたい。
WebTransportが向く場合:
- ブラウザが別のブラウザではなく、自分たちのサーバーと通信する。
- WebプラットフォームらしいStreams APIを使いたい。
- WebRTC全体の仕組みまでは必要ない。
すでに安定したWebRTC構成があるなら、WebTransportへの移行で十分に単純化できるとは限りません。
基本的なクライアントコード
使用前には必ず機能検出をします。
async function connectWebTransport(url) {
if (!("WebTransport" in globalThis)) {
throw new Error("WebTransport is not available in this browser.");
}
const transport = new WebTransport(url);
transport.closed
.then(() => {
console.log("WebTransport closed normally.");
})
.catch((error) => {
console.error("WebTransport closed unexpectedly:", error);
});
await transport.ready;
return transport;
}
const transport = await connectWebTransport("https://example.com:4433/wt");
本番では、この処理をフォールバックと一緒に包みます。WebTransportが使えない、または接続に失敗した場合は、機能に応じてWebSocket、Server-Sent Events、通常のHTTPに切り替えます。
データグラムを送る
データグラムは、古いメッセージの価値がすぐ下がる頻繁な状態更新に向いています。
const writer = transport.datagrams.writable.getWriter();
const encoder = new TextEncoder();
await writer.write(encoder.encode(JSON.stringify({
type: "cursor",
x: 240,
y: 180,
t: Date.now()
})));
データグラムのペイロードは、各メッセージだけで意味が分かるように設計します。前のデータグラムがすべて届く前提にしてはいけません。
向いているデータ:
- 現在のプレイヤー位置。
- 最新のカーソル位置。
- センサー値。
- 入力状態やプレゼンスのハートビート。
- ライブプレビュー状態。
向いていないデータ:
- 決済操作。
- アカウント変更。
- 厳密な順序が必要な文書編集。
- 監査が必要な操作。
信頼性のあるストリームを使う
受信側がすべてのバイトを順番に受け取る必要があるなら、ストリームを使います。
const stream = await transport.createBidirectionalStream();
const writer = stream.writable.getWriter();
const reader = stream.readable.getReader();
const encoder = new TextEncoder();
const decoder = new TextDecoder();
await writer.write(encoder.encode("hello"));
const { value } = await reader.read();
if (value) {
console.log(decoder.decode(value));
}
await writer.close();
関係のない処理は別々のストリームに分けます。そうすれば、大きな転送が小さな制御メッセージを待たせにくくなります。
本番前チェックリスト
WebTransportを出す前に、経路全体を確認します。
- 対象ユーザーのブラウザ対応。
- サーバーのHTTP/3対応。
- TLS証明書と安全なコンテキスト。
- ファイアウォールや社内ネットワークでのUDP/QUICの扱い。
- CDNまたはリバースプロキシの対応。
- 長時間セッションでのロードバランシング。
- 接続失敗率、再試行率、フォールバック使用率の監視。
- ストリームのバックプレッシャー処理。
- データグラムのメッセージサイズ制限。
- セッション開始時の認証と認可。
難しいのはブラウザAPIそのものより、ネットワークとサーバー運用であることが多いです。
フォールバック戦略
実用的なフォールバックは次のようになります。
まずWebTransportを試す
使えない、または接続に失敗したら:
双方向の信頼できる通信にはWebSocketを使う
双方向が不要なら:
サーバープッシュにはServer-Sent Eventsを使う
リアルタイム性が必須でないなら:
fetchのポーリングを使う
トランスポートが変わっても、製品の挙動は予測できる状態にします。例えばダッシュボードは遅いポーリングに落とせますが、リアルタイムゲームでは対象ルームを無効にする判断が必要かもしれません。
WebTransportが向いている場面
信頼性が必要なデータと、低遅延のベストエフォートデータが混在するアプリでは、WebTransportを評価する価値があります。
- マルチプレイヤーゲームの状態更新と、信頼できる試合イベント。
- 共同編集のカーソルと、信頼できる文書操作。
- 高頻度テレメトリと、信頼できる制御コマンドを持つライブダッシュボード。
- リモートデバイス制御での状態更新とコマンドストリーム。
- サーバー側リアルタイムデータチャネルが必要なメディア周辺アプリ。
共通点は混合トラフィックです。一部のデータは必ず届く必要があり、一部のデータは新鮮であることが重要です。
使わないほうがよい場面
次のような場合は避けたほうがよいです。
- 通常のRESTやfetch APIで足りる。
- 1本のWebSocketで問題をきれいに解決できる。
- 古いブラウザとの互換性が必要。
- デプロイ経路がHTTP/3を安定して支えられない。
- ブラウザ同士のピアツーピア通信が必要。
- チームがトランスポート層のフォールバックを運用したくない。
新しいトランスポート技術は、実際の製品上の痛みを減らすときにだけ価値があります。
まとめ
WebTransportは、ブラウザアプリにHTTP/3ベースのクライアント-サーバートランスポートを提供し、信頼性のあるストリームと信頼性を保証しないデータグラムを扱えます。価値はWebSocketを全面的に置き換えることではなく、異なる配送要件を持つリアルタイムデータを1つのセッションで扱えることです。
本当にその柔軟性が必要な場合に、機能検出、フォールバック、本番監視と一緒に導入してください。
ブラウザローカルツールを無料で試す →