WebTransport over HTTP/3のプロトコル仕様

WebSocketに変わる、Webの新しい双方向通信仕様 WebTransportの標準化・実装が進められています。

このWebTransportではHTTP/3の特徴を活かし、パケットの順番が入れ替わったり、パケットロスがあったとしても受け取った順番に処理を行うことが出来ます。DATAGRAM拡張を使えば、パケットロスしたデータも再送不要にできます。

前回紹介した通り、WebTransportは「WebTransportover QUIC」や「WebTransportover HTTP/3」がありましたが、HTTP/3を使う方向で議論が進んでいます。
asnokaze.hatenablog.com

Chromeの開発者メーリングリストでは、この「WebTransport over HTTP/3」実装が進められている事が書かれています。
groups.google.com

そこで、今回はプロトコルの仕様部分について確認していきます。

目次

概要

WebTransport over HTTP/3」では、HTTP/3のコネクションは確立されたところから始まります。仕様通り順番に説明していきます

  • コネクション確立後、WebTransportに対応している事をお互いに示す
  • CONNECTメソッドでWebTransport通信を開始する
  • ストリーム, DATAGRAMを行う

f:id:ASnoKaze:20210418002323p:plain

コネクション確立後、WebTransportに対応している事をお互いに示す

通常通りHTTP/3コネクションを確立したあとに、クライアントとサーバはそれぞれ自身がWebTransportに対応している事を通知し合います。

具体的には、SETTINGSフレームでSETTINGS_ENABLE_WEBTRANSPORTを1に設定して送信します。DATAGRAMフレームを使うので、QUICレイヤでDATAGRAMを有効化しておく必要があります。

CONNECTメソッドでWebTransport通信を開始する

JavaScriptからはURLを指定して通信が開始されます。
```
new WebTransport(url)
```

このURLに対してCONNECTメソッドのリクエストを送信することで、WebTransport用の通信が開始されます。このCONNECTメソッドは「RFC8441 WebSockets over HTTP/2」で拡張されたヘッダを持ちます。

  • :protocol疑似ヘッダに "webtransport" を指定されます
  • :scheme疑似ヘッダには "https" が指定されます
  • :path, :authority 疑似ヘッダはコネクションを開始した際のURLに沿って設定されます

このリクエストに対してステータスコード200が返されると、WebTransportの通信が進められます。なお、このCONNECTメソッドを送信したストリームIDをセッションIDと呼びます。

ストリーム, DATAGRAM通信を行う

HTTP/3コネクション上に、アプリケーションが実際にデータを送信するQUICストリームをオープンします。これらは、セッションIDと紐付けて利用されます。

以下の通信の種類があります

  • 単方向ストリーム
  • クライアント開始双方向ストリーム
  • サーバ開始双方向ストリーム
  • DATAGRAMフレームの送信
単方向ストリーム

HTTP/では単方向ストリームを使用する際に、まずストリームタイプの値を送信します。

WebTransportではストリームタイプ0x54でストリームが開始されます。続いて紐づくセッションIDを送信し、その後データを送ることが出来ます

f:id:ASnoKaze:20210418001247p:plain

クライアント開始双方向ストリーム

新しいWEBTRANSPORT_STREAMフレームでストリームが開始されます。紐づくセッションIDを送信し、その後データが続きます。

f:id:ASnoKaze:20210418001311p:plain

サーバ開始双方向ストリーム

サーバ開始の双方向ストリームは通常HTTP/3では行わないません。この仕様では、QUICのルールに基づいてサーバから双方向通信ストリームをオープンします

f:id:ASnoKaze:20210418001326p:plain

DATAGRAMフレームの送信

QUIC DATAGRAMフレームの利用方法は「Using QUIC Datagrams with HTTP/3」で定義されています。(今後変更される予定です

DATAGRAMフレームで、紐づくセッションIDを送信し、その後データが続きます。

f:id:ASnoKaze:20210418001346p:plain

コネクションプーリング

HTTP/3ではコネクション上で複数のHTTPリクエストを送信することが出来ます。別タブで同じサーバに対してHTTPリクエストを送信したりする際も単一のコネクションが使用されます。

それと同じ用に、「new WebTransport(url)」で同一通信する際も同一コネクションを使う事ができるでしょう。

このようなコネクションプーリングの仕組みは現在議論されている段階です。今の所、SETTINGS_ENABLE_WEBTRANSPORTに2を設定することで、コネクションプーリングに対応していることを相手に通知する方法が考えられています。詳しくは下記を参照ください

github.com

その他

DATAGRAMフレームについては現在議論が進められている段階です。特にHTTP/3から利用する場合のフォーマットは今後変更される可能性があります。

github.com