WebTransport

W3C 作業草案,

この文書の詳細情報
このバージョン:
https://www.w3.org/TR/2026/WD-webtransport-20260706/
最新公開バージョン:
https://www.w3.org/TR/webtransport/
編集者ドラフト:
https://w3c.github.io/webtransport/
履歴:
https://www.w3.org/standards/history/webtransport/
フィードバック:
public-webtransport@w3.org 件名 “[webtransport] … メッセージのトピック …” (アーカイブ)
GitHub
仕様内でインライン
編集者:
Nidhi Jaju (Google)
Victor Vasiliev (Google)
Jan-Ivar Bruaroey (Mozilla)
以前の編集者:
Bernard Aboba (Microsoft Corporation)
Peter Thatcher (Google)
Robin Raymond (Optical Tone Ltd.)
Yutaka Hirano (Google)

概要

この文書は、ブラウザとサーバー間でデータの送受信を可能にするためのECMAScript APIセットをWebIDLで定義し、[WEB-TRANSPORT-OVERVIEW]を利用します。 この仕様は、IETF WEBTRANSワーキンググループによって策定されているプロトコル仕様と連携して開発されています。

この文書のステータス

このセクションは、公開時点でのこの文書のステータスについて説明します。最新のW3C出版物の一覧やこの技術報告書の最新版は、W3C技術報告書インデックスに掲載されています。

この文書は、WebTransportワーキンググループ によって、勧告トラックを用いて作業草案として公開されました。この文書はW3C勧告になることを目指しています。

この文書へのフィードバックやコメントは歓迎します。イシューを提出 するか、GitHubリポジトリをご利用ください。

作業草案としての公開は、W3Cおよびその会員による支持を意味するものではありません。この文書は草案であり、随時更新、差し替え、または廃止される可能性があります。進行中の作業以外として引用するのは不適切です。

この文書はW3C特許ポリシーの下で活動するグループによって作成されました。 W3Cは、グループの成果物に関して行われた特許開示の公開リストを維持しています。 そのページには特許開示方法の案内も含まれています。 個人が本質的な請求項Essential Claim(s)を含むと考える特許について実際に知っている場合は、W3C特許ポリシー第6節に従って情報を開示する必要があります。

この文書は、2025年8月18日W3Cプロセス文書に従って管理されています。

1. はじめに

このセクションは規範的ではありません。

この仕様は、[WEB-TRANSPORT-OVERVIEW]を使用して、サーバーへのデータ送信およびサーバーからのデータ受信を行います。WebSocketsのように使用できますが、複数ストリーム、単方向ストリーム、順不同配信、信頼性のある転送および信頼性のない転送のサポートがあります。

注: 本仕様で示されているAPIは、IETF WEBTRANS WGで進行中の作業に基づく暫定案です。[WEB-TRANSPORT-HTTP3] および [WEB-TRANSPORT-HTTP2] の仕様は進行中であるため、今後プロトコルやAPIが大きく変更される可能性があります。

2. 適合性

規範的でないと明記されたセクションだけでなく、著者向けガイドライン、図、例、および本仕様書内の注記も全て非規範的です。それ以外は全て規範的です。

「MUST」「MUST NOT」「REQUIRED」「SHALL」「SHALL NOT」「SHOULD」「SHOULD NOT」「RECOMMENDED」「NOT RECOMMENDED」「MAY」「OPTIONAL」といったキーワードは、[RFC2119] および [RFC8174] の定義に従い、ここで示されるように全て大文字で現れる場合のみ、同様に解釈されます。

本仕様は、ここに含まれるインターフェースを実装するユーザーエージェント製品単体に適用される適合性基準を定義します。

アルゴリズムや具体的な手順として記述された適合要件は、最終結果が同等である限り、どのような方法で実装してもかまいません。(特に、本仕様で定義されているアルゴリズムは理解しやすいように意図されており、性能面を考慮しているものではありません。)

本仕様で定義されるAPIをECMAScriptを用いて実装する場合、Web IDL仕様 [WEBIDL] で定義されるECMAScriptバインディングと用語に従い、一貫した方法で実装しなければなりません。

3. プロトコルの概念

WebTransportの主要なプロトコル概念は「セッション」と「ストリーム」の2つです。各WebTransportセッションは複数のWebTransportストリームを含むことができます。

これらは、アプリケーションレベルのAPI構造であるプロトコル名と混同しないでください。

3.1. WebTransportセッション

WebTransportセッションは、HTTP/3またはHTTP/2の基盤となるコネクション上のWebTransportのセッションです。 プーリングが有効な場合、1つのコネクション上に複数のWebTransportセッションが存在することがあります。

WebTransportセッションには、[WEB-TRANSPORT-OVERVIEW]で定義された以下の機能があります:

機能 定義
データグラムを送信する [WEB-TRANSPORT-OVERVIEW] セクション 4.2
データグラムを受信する [WEB-TRANSPORT-OVERVIEW] セクション 4.2
外向き単方向ストリームを作成する [WEB-TRANSPORT-OVERVIEW] セクション 4.3
双方向ストリームを作成する [WEB-TRANSPORT-OVERVIEW] セクション 4.3
内向き単方向ストリームを受信する [WEB-TRANSPORT-OVERVIEW] セクション 4.3
双方向ストリームを受信する [WEB-TRANSPORT-OVERVIEW] セクション 4.3

WebTransportセッション session排出中とは、CONNECTストリームが サーバにより正常にクローズするよう要求された場合を指す(詳細は [WEB-TRANSPORT-OVERVIEW] セクション 4.1 参照)。

終了するには、オプションの整数 code およびオプションのバイト列 reason と共に WebTransportセッション session を 終了するには、[WEB-TRANSPORT-OVERVIEW] セクション 4.1 に従うこと。

WebTransportセッション session は、オプションの 整数 code およびバイト列 reasonと共に CONNECTストリーム がサーバによってクローズされたときに 終了状態 になる(詳細は [WEB-TRANSPORT-OVERVIEW] セクション 4.1 参照)。

3.2. WebTransportストリーム

WebTransportストリーム は、WebTransportセッション 上で順序どおり信頼できる バイト・ストリームの概念である。(詳細は [WEB-TRANSPORT-OVERVIEW] セクション 4.3

WebTransportストリーム は、内向き単方向外向き単方向双方向のいずれかである。

ストリーム に送信されたデータは 区別されないバイト列として配送されます。 送信側で一度に書き込まれたバイト数は、 受信側で一度に読み込まれるバイト数と一致しない場合があります。 個別の書き込みがまとめられて1つのバイト列として配送されることもあり、 1回の書き込みが個別に配送されることもあります。

これは、アトミック書き込みも含みます。 これはフロー制御デッドロックを防止するためのものであり、 データをまとめて配送することを保証するものではありません。

送信者と受信者の間でメッセージ境界が維持される メッセージベースのプロトコルに依存するアプリケーションは、 メッセージを再構築できるようにフレーミング層を追加する必要があります。

WebTransport ストリーム には次の機能があります:

機能 定義 着信単方向 送信単方向 双方向
バイト送信(FIN 付きの可能性あり) [WEB-TRANSPORT-OVERVIEW] Section 4.3 いいえ はい はい
バイト受信(FIN 付きの可能性あり) [WEB-TRANSPORT-OVERVIEW] Section 4.3 はい いいえ はい
WebTransport ストリーム の受信中断 [WEB-TRANSPORT-OVERVIEW] Section 4.3 はい いいえ はい
WebTransport ストリーム の送信中断 [WEB-TRANSPORT-OVERVIEW] Section 4.3 いいえ はい はい

WebTransport ストリーム には次のシグナルがあります:

イベント 定義 着信単方向 送信単方向 双方向
受信中断 [WEB-TRANSPORT-OVERVIEW] Section 4.3 いいえ はい はい
送信中断 [WEB-TRANSPORT-OVERVIEW] Section 4.3 はい いいえ はい
フロー制御 [WEB-TRANSPORT-OVERVIEW] Section 4.3 いいえ はい はい

4. WebTransportDatagramsWritable インターフェース

WebTransportDatagramsWritableは、WritableStream であり、 データグラムの送信のための送信ストリーミング機能を提供します。

[Exposed=(Window,Worker), SecureContext, Transferable]
interface WebTransportDatagramsWritable : WritableStream {
  attribute WebTransportSendGroup? sendGroup;
  attribute long long sendOrder;
};

4.1. 内部スロット

WebTransportDatagramsWritable オブジェクトは以下の内部スロットを持ちます。

内部スロット 説明 (非規範的)
[[OutgoingDatagramsQueue]] 送信用データグラム、タイムスタンプ、およびデータグラムが送信または破棄されたときに解決される Promise のタプルのキュー。
[[Transport]] この WebTransport が所有する WebTransportDatagramsWritable
[[SendGroup]] オプションの WebTransportSendGroup、 または null。
[[SendOrder]] オプションの送信順序番号。デフォルトは 0。
WebTransportDatagramsWritableWebTransport transportsendGroupsendOrder を与えて生成するには、以下の手順を行う。
  1. stream を、以下を持つ 新しい WebTransportDatagramsWritable とする:

    [[OutgoingDatagramsQueue]]

    空のキュー

    [[Transport]]

    transport

    [[SendGroup]]

    sendGroup

    [[SendOrder]]

    sendOrder

  2. writeDatagramsAlgorithm を、writeDatagramstransportstream で実行するアクションとする。

  3. セットアップ streamwriteAlgorithmwriteDatagramsAlgorithm に設定する。

  4. stream を返す。

4.2. 属性

sendGroup, WebTransportSendGroup, null可能

ゲッター手順:

  1. this[[SendGroup]] を返す。

セッター手順(valueを与える):

  1. valueがnullでなく、かつ value.[[Transport]]this.[[Transport]] でない場合、InvalidStateErrorをスローする。

  2. this.[[SendGroup]]valueに設定する。

sendOrder, long long

ゲッター手順:

  1. this[[SendOrder]] を返す。

セッター手順(valueを与える):

  1. this.[[SendOrder]]valueに設定する。

4.3. 手順

writeDatagrams アルゴリズムはtransportおよびwritableをパラメータ、dataを入力とし、次の手順で定義されます:

  1. timestampを現在を表すタイムスタンプとする。

  2. dataBufferSource オブジェクトでない場合、TypeError却下された promiseを返す。

  3. datagramstransport.[[Datagrams]]とする。

  4. datagrams.[[OutgoingMaxDatagramSize]]dataの[[ByteLength]]より小さい場合、undefinedでresolveされたpromiseを返す。

  5. promiseを新しいpromiseとする。

  6. bytesdataが表すバイトのコピーとする。

  7. chunkbytestimestamppromiseのタプルとする。

  8. writable.[[OutgoingDatagramsQueue]]chunkをエンキューする。

  9. writable.[[OutgoingDatagramsQueue]] の長さが datagrams.[[OutgoingMaxBufferedDatagrams]] 未満なら、promiseをundefinedで解決する

  10. promiseを返す。

注: 関連するWritableStream は、そのストリームでwriteDatagramsによって返されたpromiseが全て解決されたときのみwriteDatagramsを呼び出します。したがって、タイムスタンプと有効期限は、ウェブ開発者が WritableStreamDefaultWriter.ready に注意を払う場合のみ適切に動作します。

sendDatagrams するには、WebTransport オブジェクトtransportWebTransportDatagramsWritable オブジェクトwritableで、ネットワークタスクをキューし transportで以下のステップを実行します:

  1. queuewritable.[[OutgoingDatagramsQueue]] のコピーとする。

    注: 上記のコピーおよびネットワークタスクのキューは最適化できます。

  2. maxSizetransport.[[Datagrams]].[[OutgoingMaxDatagramSize]] とする。

  3. durationtransport.[[Datagrams]].[[OutgoingDatagramsExpirationDuration]] とする。

  4. durationがnullなら、duration実装定義値に設定する。

  5. 次のステップを並行して実行:

    1. queueが空でない間:

      1. bytestimestamppromisequeueの先頭要素から取得する。

      2. timestampからdurationミリ秒以上経過している場合:

        1. queueの先頭要素を削除する。

        2. ネットワークタスクをキューしtransportpromiseをundefinedで解決する。

      3. それ以外の場合、このループを終了する。

    2. transport.[[State]]"connected"でなければ、何もせず終了する。

    3. queueが空でない間:

      1. bytestimestamppromisequeueの先頭要素から取得する。

      2. bytesの長さがmaxSize以下の場合:

        1. bytesを即座にネットワークに送信できない場合、このループを終了する。

        2. データグラムの送信transport.[[Session]]bytesで行う。

      3. queueの先頭要素を削除する。

      4. ネットワークタスクをキューし transportpromiseをundefinedで解決する。

ユーザーエージェントは、WebTransport オブジェクトで [[State]]"connecting" または "connected" であるものについて、 アソシエイトされた WebTransportDatagramsWritable オブジェクトの一部(送信順序ルールによって決定)に対して sendDatagrams を実行しなければならない。アルゴリズムが進行可能な場合はできる限り早く実行すべきである。

注記: トランスポートの [[State]]"connecting" の間もデータグラムの書き込みは許可されている。 データグラムは [[OutgoingDatagramsQueue]] に格納され、 "connected"状態と同じ方法で 破棄できる。トランスポートの [[State]]"connected" になった時、キューに格納されたデータグラムの送信が開始される。

送信順序ルール とは、送信は通常、このトランスポートで送信予定のキュー済みストリームやデータグラム、そしてこれからキューされるストリームやデータグラムと インターリーブできるが、同じ [[SendGroup]] かつ [[SendOrder]] がより高い値のストリームやデータグラムで、 エラーではなく、フロー制御によって ブロックされていないものの送信されるまで、送信は阻害されなければならない。

注記: デフォルトの null sendGroup は有効な sendGroup である。

5. WebTransportDatagramDuplexStream インターフェース

WebTransportDatagramDuplexStreamは、汎用的なデュプレックスストリームです。

[Exposed=(Window,Worker), SecureContext]
interface WebTransportDatagramDuplexStream {
  WebTransportDatagramsWritable createWritable(
      optional WebTransportSendOptions options = {});
  readonly attribute ReadableStream readable;

  readonly attribute unsigned long maxDatagramSize;
  attribute unrestricted double? incomingMaxAge;
  attribute unrestricted double? outgoingMaxAge;
  attribute unsigned long incomingMaxBufferedDatagrams;
  attribute unsigned long outgoingMaxBufferedDatagrams;
};

5.1. 内部スロット

WebTransportDatagramDuplexStream オブジェクトは以下の内部スロットを持ちます。

内部スロット 説明 (非規範的)
[[Transport]] WebTransport は、この WebTransportDatagramDuplexStream を所有する。
[[Readable]] 受信データグラム用の ReadableStream
[[ReadableType]] 受信データグラムに使用される ReadableStreamType
[[Writables]] 順序付き集合 で、初期状態では空の WebTransportDatagramsWritable ストリーム。
[[IncomingDatagramsQueue]] 受信データグラムとタイムスタンプのペアのキュー。
[[IncomingDatagramsPullPromise]] pullDatagrams によって設定される、受信データグラムを待つためのPromise。
[[IncomingMaxBufferedDatagrams]] 受信キューの長さ(データグラム数)を表す unsigned long。 この数を超えた場合、キュー先頭からデータグラムが破棄される。
[[IncomingDatagramsExpirationDuration]] 受信データグラムの有効期限(ミリ秒)を表す unrestricted double。 または null。
[[OutgoingMaxBufferedDatagrams]] 基礎となるシンクの送信キュー長(データグラム数)を表す unsigned long。 この数を超えるとバックプレッシャーがかかる。
[[OutgoingDatagramsExpirationDuration]] 送信データグラムの有効期限(ミリ秒)を表す unrestricted double の値。 または null。
[[OutgoingMaxDatagramSize]] 送信データグラムの最大サイズを表す整数。
最大データグラムサイズは使用しているプロトコルによって異なる。 HTTP/3 [WEB-TRANSPORT-HTTP3] では、 値は経路の MTU の推定値に関係し、 実装依存の量だけオーバーヘッド分減算される。 HTTP/2 [WEB-TRANSPORT-HTTP2] には相当する上限はない。

データグラムの処理は一般に全体をメモリ保持するため、 実装はサイズ上限を設けることになる。 プロトコル拡張が将来こうしたサイズ制限の通知を 全バリアントに対して可能にすることもあり得る。

ユーザーエージェントは、[[OutgoingMaxDatagramSize]]WebTransport オブジェクトの [[State]]"connecting" または "connected" である場合に更新してもよい。

作成するには、 WebTransportDatagramDuplexStream を、WebTransport transportreadable および readableType を指定して次の手順を行う。
  1. stream新しい WebTransportDatagramDuplexStream として次のように初期化する:

    [[Transport]]

    transport

    [[Readable]]

    readable

    [[ReadableType]]

    readableType

    [[Writables]]

    空の 順序付き集合

    [[IncomingDatagramsQueue]]

    空のキュー

    [[IncomingDatagramsPullPromise]]

    null

    [[IncomingMaxBufferedDatagrams]]

    実装依存の値

    [[IncomingDatagramsExpirationDuration]]

    null

    [[OutgoingMaxBufferedDatagrams]]

    実装依存の値

    この実装依存の値は、適切なスループットを確保しつつ、 伝送データの迅速性を損なわないように調整されるべき

    [[OutgoingDatagramsExpirationDuration]]

    null

    [[OutgoingMaxDatagramSize]]

    実装依存の整数値

  2. stream を返す

5.2. メソッド

createWritable(options)

WebTransportDatagramsWritable を作成する。 呼び出されたとき、ユーザーエージェントは 次の手順を実行しなければならない:

  1. transport を、this に関連付けられた WebTransport オブジェクトとする。

  2. sendGroupoptionssendGroup とする。

  3. sendGroup が null でなく、かつ sendGroup.[[Transport]]this.[[Transport]] でない場合、 TypeError投げる

  4. transport.[[State]]"closed" または "failed" の場合、 InvalidStateError投げる

  5. sendOrderoptionssendOrder とする。

  6. transportsendGroup、および sendOrderWebTransportDatagramsWritable作成する結果を返す。

5.3. 属性

readable, 型: ReadableStream、読み取り専用

getter の手順:

  1. this.[[Readable]] を返す。

incomingMaxAge, 型: unrestricted double、nullable

getter の手順:

  1. this.[[IncomingDatagramsExpirationDuration]] を返す。

setter の手順(value を与えられた場合):

  1. value が負の値または NaN の場合、RangeError投げる

  2. value0 の場合、value を null に設定する。

  3. this.[[IncomingDatagramsExpirationDuration]]value を設定する。

maxDatagramSize, 型: unsigned long、読み取り専用

WebTransportDatagramsWritable に渡せるデータの最大サイズ。 getter の手順は、this.[[OutgoingMaxDatagramSize]] を返す。

outgoingMaxAge, 型: unrestricted double、nullable

getter の手順:

  1. this[[OutgoingDatagramsExpirationDuration]] を返す。

setter の手順(value を与えられた場合):

  1. value が負の値または NaN の場合、RangeError投げる

  2. value0 の場合、value を null に設定する。

  3. this.[[OutgoingDatagramsExpirationDuration]]value を設定する。

incomingMaxBufferedDatagrams, 型: unsigned long

getter の手順:

  1. this.[[IncomingMaxBufferedDatagrams]] を返す。

setter の手順(value を与えられた場合):

  1. value1 未満の場合、value1 に設定する。

  2. this.[[IncomingMaxBufferedDatagrams]]value を設定する。

outgoingMaxBufferedDatagrams, 型: unsigned long

getter の手順:

  1. this.[[OutgoingMaxBufferedDatagrams]] を返す。

setter の手順(value を与えられた場合):

  1. value1 未満の場合、value1 に設定する。

  2. this.[[OutgoingMaxBufferedDatagrams]]value を設定する。

5.4. 手順

pullDatagrams するには、 WebTransport オブジェクト transport を与えて次の手順を実行する:

  1. datagramstransport.[[Datagrams]] とする。

  2. アサート: datagrams.[[IncomingDatagramsPullPromise]] は null である。

  3. queuedatagrams.[[IncomingDatagramsQueue]] とする。

  4. もし queue が空なら、以下を行う:

    1. datagrams.[[IncomingDatagramsPullPromise]] に新しい promise を設定する。

    2. datagrams.[[IncomingDatagramsPullPromise]] を返す。

  5. datagram および timestamp を、queue からデキュー した結果とする。

  6. もし datagrams.[[ReadableType]]"bytes" であるなら、以下を行う:

    1. datagrams.[[Readable]]現在の BYOB リクエストビュー が null でない場合、次を実行する:

      1. viewdatagrams.[[Readable]]現在の BYOB リクエスト ビュー とする。

      2. viewバイト長datagram のサイズより小さい場合、 RangeError却下された promiseを返す。

      3. elementSize を、view.[[TypedArrayName]] について 型付き配列コンストラクター表 で指定される要素サイズとする。 view に [[TypedArrayName]] 内部スロットがない場合 (すなわち、それが DataView である場合)、 elementSize を 0 とする。

      4. elementSize が 1 でない場合、TypeError却下された promiseを返す。

    2. バイトからプルして、datagramdatagrams.[[Readable]] に取り込む。

  7. それ以外の場合:

    1. chunkdatagram を表す新たな Uint8Array オブジェクトとする。

    2. Enqueue chunktransport.[[Datagrams]].[[Readable]] に渡す。

  8. undefined で解決される promise を返す。

receiveDatagrams の手順は、 WebTransport オブジェクト transport を指定して次の通り:

  1. timestamp を現在時刻を表すタイムスタンプとする。

  2. queuedatagrams.[[IncomingDatagramsQueue]] とする。

  3. durationdatagrams.[[IncomingDatagramsExpirationDuration]] とする。

  4. duration が null なら 実装依存の値に設定する。

  5. sessiontransport.[[Session]] とする。

  6. session 上で 受信可能なデータグラム がある間:

    1. datagramreceive a datagram の結果とする。

    2. timestamp を現在時刻を表すタイムスタンプとする。

    3. chunkdatagramtimestamp のペアとする。

    4. Enqueue chunkqueue に追加する。

  7. toBeRemovedqueue の長さから datagrams.[[IncomingMaxBufferedDatagrams]] を引いた値とする。

  8. toBeRemoved が正の値の場合、dequeuequeue に対して toBeRemoved(切り捨てで)回繰り返す。

  9. queue が空でない間:

    1. bytestimestampqueue の先頭要素とする。

    2. timestamp から duration ミリ秒以上経過していたら dequeue queue を行う。

    3. そうでない場合、このループを break する。

  10. queue が空でなく、かつ datagrams.[[IncomingDatagramsPullPromise]] が null でない場合:

    1. bytestimestampqueue から dequeue した結果とする。

    2. promisedatagrams.[[IncomingDatagramsPullPromise]] とする。

    3. datagrams.[[IncomingDatagramsPullPromise]] を null に設定する。

    4. ネットワークタスクをキューし、transport に対して以下を実行する:

      1. chunkUint8Array オブジェクトで bytes を表す新しいものとする。

      2. Enqueue chunkdatagrams.[[Readable]] に追加する。

      3. Resolve promise を undefined で解決する。

ユーザーエージェントは、receiveDatagramsWebTransport オブジェクトで [[State]]"connected" の場合、アルゴリズムが進行可能なときはできるだけ速やかに実行すべきである。

6. WebTransport インターフェース

WebTransportは、[WEB-TRANSPORT-OVERVIEW]で定義された基盤となるトランスポート機能へのAPIを提供します。

[Exposed=(Window,Worker), SecureContext]
interface WebTransport {
  constructor(USVString url, optional WebTransportOptions options = {});

  Promise<WebTransportConnectionStats> getStats();
  [NewObject] Promise<Uint8Array> exportKeyingMaterial(BufferSource label, BufferSource context, unsigned long outputLength);
  readonly attribute Promise<undefined> ready;
  readonly attribute WebTransportReliabilityMode reliability;
  readonly attribute WebTransportCongestionControl congestionControl;
  attribute [EnforceRange] unsigned short? anticipatedConcurrentIncomingUnidirectionalStreams;
  attribute [EnforceRange] unsigned short? anticipatedConcurrentIncomingBidirectionalStreams;
  [SameObject] readonly attribute Headers? responseHeaders;
  readonly attribute DOMString protocol;

  readonly attribute Promise<WebTransportCloseInfo> closed;
  readonly attribute Promise<undefined> draining;
  undefined close(optional WebTransportCloseInfo closeInfo = {});

  readonly attribute WebTransportDatagramDuplexStream datagrams;

  Promise<WebTransportBidirectionalStream> createBidirectionalStream(
      optional WebTransportSendStreamOptions options = {});
  /* a ReadableStream of WebTransportBidirectionalStream objects */
  readonly attribute ReadableStream incomingBidirectionalStreams;

  Promise<WebTransportSendStream> createUnidirectionalStream(
      optional WebTransportSendStreamOptions options = {});
  /* a ReadableStream of WebTransportReceiveStream objects */
  readonly attribute ReadableStream incomingUnidirectionalStreams;
  WebTransportSendGroup createSendGroup();

  static readonly attribute boolean supportsReliableOnly;
};

enum WebTransportReliabilityMode {
  "pending",
  "reliable-only",
  "supports-unreliable",
};

6.1. 内部スロット

A WebTransport オブジェクトは以下の内部スロットを持つ。

内部スロット 説明 (非規範的)
[[SendStreams]] 順序付き集合 この WebTransport が所有する WebTransportSendStream の集合。
[[ReceiveStreams]] 順序付き集合 この WebTransport が所有する WebTransportReceiveStream の集合。
[[IncomingBidirectionalStreams]] ReadableStream で、 WebTransportBidirectionalStream オブジェクトからなる。
[[IncomingUnidirectionalStreams]] ReadableStream で、 WebTransportReceiveStream の集合。
[[State]] トランスポートの状態を示す列挙型。 "connecting""connected""draining""closed""failed" のいずれか。
[[Ready]] 関連する WebTransport セッション確立したときに fulfill、確立処理 が失敗した場合は reject される promise。
[[Reliability]] WebTransportReliabilityMode。 最初のホップで信頼性のない(UDP)トランスポートが利用可能か、信頼性のある(TCPフォールバック)トランスポートのみかを示す。 接続が確立されるまでは "pending" を返す。
[[CongestionControl]] WebTransportCongestionControl。 アプリケーションから要求され、ユーザーエージェントによって満たされた場合はスループット最適化または低遅延用アルゴリズムを示す。"default" も可能。
[[AnticipatedConcurrentIncomingUnidirectionalStreams]] アプリケーションがサーバーによる作成を予期する同時オープン済みの 受信単方向ストリームの数、または null。
[[AnticipatedConcurrentIncomingBidirectionalStreams]] アプリケーションがサーバーによる作成を予期する同時オープン済みの 双方向ストリームの数、または null。
[[ResponseHeaders]] Headers オブジェクトまたは null。初期値は null。
[[Protocol]] サーバーによって選択されたアプリケーションレベルのプロトコル名を示す文字列。初期値は空文字列。
[[Closed]] 関連する WebTransport オブジェクトが正常終了された時に fulfill、異常終了または初期化失敗時に reject される promise。
[[Draining]] 関連する WebTransport セッションdraining を開始した時に fulfill される promise。
[[Datagrams]] WebTransportDatagramDuplexStream
[[Session]] WebTransport セッション。この WebTransport オブジェクト用。 もしくは null。
[[NewConnection]] "no" または "yes-and-dedicated"。
[[RequireUnreliable]] UDP が必須かどうかを示すブール値。

6.2. コンストラクター

WebTransport() コンストラクターが呼び出されたとき、ユーザー エージェントは次の手順を実行しなければならない:
  1. baseURL を、this関連設定オブジェクトAPI ベース URL とする。

  2. url を、baseURL を用いて url構文解析した結果の URL レコードとする。

  3. url が失敗である場合、SyntaxError 例外を投げる

  4. urlスキームhttps でない場合、SyntaxError 例外を投げる

  5. urlフラグメントが null でない場合、SyntaxError 例外を投げる

  6. newConnection を、optionsallowPooling が true である場合は "no"、そうでなければ "yes-and-dedicated" とする。

  7. serverCertificateHashes を、optionsserverCertificateHashes とする。

  8. newConnection が "no" であり、かつ serverCertificateHashes空でない場合、NotSupportedError 例外を投げる

  9. requireUnreliable を、optionsrequireUnreliable とする。

  10. congestionControl を、optionscongestionControl とする。

  11. congestionControl"default" でなく、かつユーザーエージェントが [RFC9002] Section 7 で許可されるように、 congestionControl に最適化される輻輳制御アルゴリズムを 何もサポートしていない場合、 congestionControl"default" に設定する。

  12. protocols を、optionsprotocols とする。

  13. protocols 内の値のいずれかが複数回出現する場合、WebTransport プロトコルで定義される、 交渉されるアプリケーションプロトコルの値を構成する要素の要件に 合致しない場合、または同型符号化された 長さが 0 もしくは 512 を超える場合、SyntaxError 例外を投げる[WEB-TRANSPORT-OVERVIEW] Section 3.1.

  14. anticipatedConcurrentIncomingUnidirectionalStreams を、optionsanticipatedConcurrentIncomingUnidirectionalStreams とする。

  15. anticipatedConcurrentIncomingBidirectionalStreams を、optionsanticipatedConcurrentIncomingBidirectionalStreams とする。

  16. datagramsReadableType を、optionsdatagramsReadableType とする。

  17. incomingDatagrams を、新しい ReadableStream とする。

  18. transport を、次を持つ、新たに構築された WebTransport オブジェクトとする:

    [[SendStreams]]

    空の順序付き集合

    [[ReceiveStreams]]

    空の順序付き集合

    [[IncomingBidirectionalStreams]]

    新しい ReadableStream

    [[IncomingUnidirectionalStreams]]

    新しい ReadableStream

    [[State]]

    "connecting"

    [[Ready]]

    新しい promise

    [[Reliability]]

    "pending"

    [[CongestionControl]]

    congestionControl

    [[AnticipatedConcurrentIncomingUnidirectionalStreams]]

    anticipatedConcurrentIncomingUnidirectionalStreams

    [[AnticipatedConcurrentIncomingBidirectionalStreams]]

    anticipatedConcurrentIncomingBidirectionalStreams

    [[ResponseHeaders]]

    null

    [[Protocol]]

    空文字列

    [[Closed]]

    新しい promise

    [[Draining]]

    新しい promise

    [[Datagrams]]

    undefined

    [[Session]]

    null

    [[NewConnection]]

    newConnection

    [[RequireUnreliable]]

    requireUnreliable

  19. transport.[[Datagrams]] を、transportincomingDatagrams、および datagramsReadableType を用いて WebTransportDatagramDuplexStream作成した結果に設定する。

  20. pullDatagramsAlgorithm を、transport を用いて pullDatagrams を実行する動作とする。

    注: データグラムでは 64 キビバイトのバッファーを使用することが推奨される。 これは、有効な最大 WebTransport データグラムフレームサイズが、QUIC 最大データグラムフレーム サイズの上限を持ち、その値は 64 キビバイトであることが推奨されるためである([QUIC-DATAGRAM] Section 3 を参照)。 これにより、データグラムがバッファーより大きいことによってストリームがエラーにならないことが保証される。

  21. datagramsReadableType"bytes" である場合、incomingDatagramsバイト読み取りサポート付きで 設定し、pullAlgorithmpullDatagramsAlgorithm に設定し、 highWaterMark を 0 に設定する。そうでなければ、incomingDatagrams設定し、 pullAlgorithmpullDatagramsAlgorithm に設定し、 highWaterMark を 0 に設定する。

  22. pullBidirectionalStreamAlgorithm を、transport を用いて pullBidirectionalStream を実行する動作とする。

  23. transport.[[IncomingBidirectionalStreams]]設定し、 pullAlgorithmpullBidirectionalStreamAlgorithm に設定し、 highWaterMark を 0 に設定する。

  24. pullUnidirectionalStreamAlgorithm を、transport を用いて pullUnidirectionalStream を実行する動作とする。

  25. transport.[[IncomingUnidirectionalStreams]]設定し、 pullAlgorithmpullUnidirectionalStreamAlgorithm に設定し、 highWaterMark を 0 に設定する。

  26. client を、transport関連設定オブジェクトとする。

  27. origin を、clientオリジンとする。

  28. request を、新しいリクエストとする。その URLurlclientclientservice-workers mode は "none"、 referrer は "no-referrer"、mode は "webtransport"、 credentials mode は "omit"、 cache mode は "no-store"、 policy containerclientpolicy containerdestination は ""、 originoriginWebTransport-hash listserverCertificateHashes、そしてredirect mode は "error" である。

    注: リダイレクトは追跡されない。リダイレクトによって引き起こされるネットワーク エラーは、意図的に他のネットワークエラーと区別できない。クロスオリジンコンテキストでは、これは 通常 CORS によってブロックされる情報を明らかにしてしまう。同一オリジンコンテキストでは、 ハンドシェイクを情報受け渡しのベクトルとして濫用するようアプリケーションを 助長する可能性がある。

  29. requestmethod を "CONNECT" に設定し、 method に関連付けられた :protocol 疑似ヘッダー"webtransport" に設定する。

  30. headers を、options["headers"] で埋められた新しい Headers オブジェクトとする。

  31. requestHeaders を、新しい Headers オブジェクトとする。そのヘッダーリストrequestヘッダーリストであり、ガードは "request" である。

  32. headersヘッダーリスト内の各 header について:

    1. header名前ASCII 小文字化したものが "wt-available-protocols" である場合、 TypeError を投げる。

    2. headerrequestHeaders追加する

    注: ヘッダーは Fetch の 禁止リクエストヘッダー 制限の対象となる。

  33. protocols が空でない場合、(WT-Available-Protocols, protocols 内の 構造化ヘッダー文字列項目を順にメンバーとする 構造化ヘッダーリスト) を用いて、requestヘッダーリスト内に構造化フィールド値を設定する

  34. requestフェッチし、useParallelQueue を true に設定し、processResponse を、response が与えられたときの次の手順に設定する:

    1. response および transport を用いて、WebTransport fetch response を処理する

  35. transport を返す。

ネットワーク 分割キー networkPartitionKey、および リクエスト request が与えられたとき、 WebTransport 接続を取得するには:
  1. transport を、request に関連付けられた WebTransport オブジェクトとする。

  2. url を、request現在の URL とする。

  3. newConnection を、transport.[[NewConnection]] とする。

  4. requireUnreliable を、transport.[[RequireUnreliable]] とする。

  5. webTransportHashes を、requestWebTransport-hash list 内の値とする。

  6. connection を、networkPartitionKeyurl、false、 newConnectionrequireUnreliable、および webTransportHashes を用いて接続を取得する結果とする。

  7. connection が失敗である場合、失敗を返す。

  8. connection が最初の SETTINGS フレームを受信するまで待機し、 settings を、その SETTINGS フレームを表す辞書とする。

  9. settings が値 1 の SETTINGS_ENABLE_CONNECT_PROTOCOL を含まない場合 (HTTP/2 については 0x08、Section 3 of [RFC8441] を参照。HTTP/3 については 0x08、 Section 3 of [RFC9220] を参照)、失敗を返す。

  10. settings が WebTransport に対するサーバーサポートを示さない場合、失敗を返す。 [WEB-TRANSPORT-OVERVIEW] Section 4.1.

    • HTTP/3 では、サポートには 0 より大きい値の SETTINGS_WT_ENABLED、 および値 1 の SETTINGS_H3_DATAGRAM が必要である。[WEB-TRANSPORT-HTTP3] Section 3.1.

    • HTTP/2 では、潜在的なサポートは上記の SETTINGS_ENABLE_CONNECT_PROTOCOL によってすでに示されている。 [WEB-TRANSPORT-HTTP2] Section 3.1.

  11. connection を返す。

WebTransport fetch response 処理は、 レスポンス responseWebTransport transport を指定し次の手順:
  1. responseネットワークエラーの場合、残りの手順を中止し ネットワークタスクをキューして transport に以下を実行:

    1. transport.[[State]]"closed" または "failed" の場合、これ以降の手順を中止。

    2. error を新しく create exception した WebTransportError とする。source"session"

    3. Cleanup transporterror を指定して行う。

  2. connectionresponse に関連付けられた下層接続とする。

  3. [WEB-TRANSPORT-OVERVIEW] Section 4.1 の制約に従い WebTransport セッション確立connection とサーバーの response で行い、 session を得る。 得られた下層トランスポートストリームはセッションの CONNECTストリーム と呼ぶ。

    注記: この手順は [QUIC-DATAGRAM] の トランスポートパラメータ交換も完結させる。

  4. 前ステップが失敗した場合、残りの手順を中止し ネットワークタスクをキューtransport で以下を実行:

    1. transport.[[State]]"closed" または "failed" の場合、これ以降の手順を中止。

    2. error を新しく create exception した WebTransportError とする。source"session"

    3. Cleanup transporterror を指定して行う。

  5. ユーザーエージェントが複数の輻輳制御アルゴリズムに対応している場合は、 この connection の送信に transport[[CongestionControl]] に適したものを選ぶ。

  6. ネットワークタスクをキューして transport に以下を実行:

    1. アサート: this[[Datagrams]][[OutgoingMaxDatagramSize]] は整数である。

    2. transport.[[State]]"connecting" でない場合:

      1. 並列処理terminate session を行う。

      2. これ以降の手順を中止。

    3. transport.[[State]]"connected" に設定。

    4. transport.[[Session]]session に設定。

    5. responseHeadersresponseheader list のコピーにする。

    6. Delete "wt-protocol" を responseHeaders から削除。

    7. transport.[[ResponseHeaders]] を新しい Headers オブジェクトに設定。header list は responseHeaders、guard は "immutable"。

    8. transport.[[Protocol]] を、WebTransport Protocol Framework [WEB-TRANSPORT-OVERVIEW] Section 3.1 に従い、協議されたアプリケーションプロトコルの文字列値が存在すればそれ、なければ "" に設定する。

    9. 接続がHTTP/3の場合、transport.[[Reliability]]"supports-unreliable" に設定。

    10. 接続が HTTP/2 ([WEB-TRANSPORT-HTTP2]) の場合は transport[[Reliability]]"reliable-only" に設定。

    11. resolve transport.[[Ready]] を undefined で解決する。

pullBidirectionalStreamは、 WebTransport オブジェクト transport を指定し次の手順:
  1. transport.[[State]]"connecting" なら transport.[[Ready]]fulfillment時に 以下の手順を実行しその結果を返す:

    1. pullBidirectionalStreamtransport で実行した結果を返す。

  2. transport.[[State]]"connected" でなければ、 新しい reject promise を InvalidStateError で返す。

  3. sessiontransport.[[Session]] とする。

  4. p を新しい promise とする。

  5. 並列処理で以下を行う:

    1. session双方向ストリーム受信可能になるまで待つ。

    2. internalStream双方向ストリーム受信 の結果とする。

    3. ネットワークタスクをキューtransport に以下実行:

      1. streambidirectionalStream作成 の結果 (引数 internalStream, transport) とする。

      2. Enqueue streamtransport.[[IncomingBidirectionalStreams]] に追加。

      3. resolve p を undefined で解決する。

  6. p を返す。

pullUnidirectionalStreamは、 WebTransport オブジェクト transport を指定し次の手順:
  1. transport.[[State]]"connecting" なら transport.[[Ready]]fulfillment時に 以下の手順を実行しその結果を返す:

    1. pullUnidirectionalStreamtransport で実行した結果を返す。

  2. transport.[[State]]"connected" でなければ、 新しい reject promise を InvalidStateError で返す。

  3. sessiontransport.[[Session]] とする。

  4. p を新しい promise とする。

  5. 並列処理で以下を行う:

    1. session単方向ストリーム受信可能 になるまで待つ。

    2. internalStream単方向ストリーム受信 の結果とする。

    3. ネットワークタスクをキューtransport に以下実行:

      1. streamWebTransportReceiveStream作成 の結果 (internalStream, transport) とする。

      2. Enqueue streamtransport.[[IncomingUnidirectionalStreams]] に追加。

      3. resolve p を undefined で解決する。

  6. p を返す。

6.3. 属性

ready, of type Promise<undefined>, readonly

取得時、this[[Ready]] を返す必要がある。

closed, of type Promise<WebTransportCloseInfo>, readonly

取得時、this[[Closed]] を返す必要がある。

draining, of type Promise<undefined>, readonly

取得時、this[[Draining]] を返す必要がある。

datagrams, of type WebTransportDatagramDuplexStream, readonly

このセッションでデータグラムの送受信を行うための単一のデュプレックスストリーム。 datagrams 属性のゲッター手順は次の通りとする:

  1. this[[Datagrams]] を返す。

incomingBidirectionalStreams, of type ReadableStream, readonly

ReadableStream で、サーバから受信したWebTransportBidirectionalStreamのストリームを返す。

Note: 着信ストリームに既にデータがあるかどうかはサーバの動作による。

incomingBidirectionalStreams 属性のゲッター手順は:

  1. this[[IncomingBidirectionalStreams]] を返す。

incomingUnidirectionalStreams, of type ReadableStream, readonly

サーバから受信した各WebTransportReceiveStream で表される単方向ストリームのReadableStream

Note: 着信ストリームに既にデータがあるかどうかはサーバの動作による。

incomingUnidirectionalStreamsのゲッター手順:

  1. this.[[IncomingUnidirectionalStreams]] を返す。

reliability, of type WebTransportReliabilityMode, readonly

このコネクションが信頼性なし(UDP経由)転送をサポートするか、信頼性あり(TCPフォールバック)転送のみサポートするか。 接続確立までは"pending"を返す。 ゲッター手順は this[[Reliability]]を返す。

congestionControl, of type WebTransportCongestionControl, readonly

アプリケーションがコンストラクタで指定し、ユーザーエージェントに満たされた場合はスループット最適化または低遅延最適化の輻輳制御アルゴリズムを示す。満たされない場合は値は"default"となる。 ゲッター手順は this[[CongestionControl]] を返す。

supportsReliableOnly, of type boolean, readonly

ユーザーエージェントがWebTransportセッション を信頼性のみのコネクション上でサポートする場合はtrue、そうでなければfalseを返す。

anticipatedConcurrentIncomingUnidirectionalStreams, of type unsigned short, nullable

アプリがサーバで同時オープンされると予測する 着信単方向ストリーム数を指定できる。 nullでなければ、ユーザーエージェントは [[AnticipatedConcurrentIncomingUnidirectionalStreams]] をサーバとのネゴシエーションで考慮しラウンドトリップ削減を試みるべきである。

ゲッター手順は this[[AnticipatedConcurrentIncomingUnidirectionalStreams]] を返す。

セッター手順(value 時)は this[[AnticipatedConcurrentIncomingUnidirectionalStreams]]value を設定する。

anticipatedConcurrentIncomingBidirectionalStreams, of type unsigned short, nullable

アプリがサーバで同時オープンされると予測する 双方向ストリーム数を指定できる。 nullでなければ、ユーザーエージェントは [[AnticipatedConcurrentIncomingBidirectionalStreams]] をサーバとのネゴシエーションで考慮しラウンドトリップ削減を試みるべきである。

ゲッター手順は this[[AnticipatedConcurrentIncomingBidirectionalStreams]] を返す。

セッター手順(value 時)は this[[AnticipatedConcurrentIncomingBidirectionalStreams]]value を設定する。

Note: anticipatedConcurrentIncomingUnidirectionalStreams または anticipatedConcurrentIncomingBidirectionalStreams を設定しても、アプリが予測する本数のストリームを必ず受信できる保証はない。

responseHeaders Headers 型、readonly、nullable

WebTransportセッションが確立された後、 サーバーによって設定されたアプリケーションレベルのレスポンスヘッダーを保持します(あれば)。初期値はnullです。 ゲッター手順は this[[ResponseHeaders]] を返すことです。

protocol DOMString 型、readonly

WebTransportセッションが確立され、 コンストラクタオプション protocols に空でない配列が渡された場合は、サーバーによって選択されたアプリケーションレベルプロトコルを返します(あれば)。 それ以外の場合は空文字列を返します。 ゲッター手順は this[[Protocol]] を返すことです。

6.4. メソッド

close(closeInfo)

WebTransport オブジェクトに関連付けられた WebTransport セッションを終了する。 呼び出されたとき、ユーザーエージェントは次の手順を実行しなければならない:

  1. transportthis とする。

  2. transport.[[State]]"closed" または "failed" である場合、これらの手順を中止する。

  3. transport.[[State]]"connecting" である場合:

    1. error を、新たに 作成された WebTransportError とし、その source"session" とする。

    2. error を用いて transportクリーンアップする。

    3. これらの手順を中止する。

  4. sessiontransport.[[Session]] とする。

  5. codecloseInfo.closeCode とする。

  6. reasonString を、 closeInfo.reason の最大の 符号単位接頭辞であって、その接頭辞を UTF-8 符号化したものの 長さが 1024 を超えないものとする。

  7. reason を、reasonStringUTF-8 符号化したものとする。

  8. 並列にcodereason を用いて session終了する。

    注:これはまた、 transport.[[SendStreams]] および [[ReceiveStreams]] に含まれる WebTransport ストリーム上の 送信を中止するか、または 受信を 中止する。

  9. AbortError および closeInfo を用いて transportクリーンアップする。

getStats()

この WebTransport下位接続に関する統計を収集し、 結果を非同期に報告する。

呼び出されたとき、ユーザーエージェントは次の手順を実行しなければならない:

  1. transportthis とする。

  2. p を新しい promise とする。

  3. transport.[[State]]"failed" である場合、pInvalidStateError拒否し、これらの手順を中止する。

  4. 次の手順を並列に実行する:

    1. transport.[[State]]"connecting" である場合、それが変化するまで待つ。

    2. transport.[[State]]"failed" である場合、 pInvalidStateError拒否するため、transportネットワークタスクをキューに入れた後、 これらの手順を中止する。

    3. transport.[[State]]"closed" である場合、 p をその接続について利用可能な最新の統計で 解決するため、transportネットワークタスクをキューに入れた後、 これらの手順を中止する。それらの統計が収集される正確な時点は 実装定義である。

    4. gatheredStats を、 WebTransportConnectionStats および WebTransportDatagramStats辞書メンバーを正確に埋めるために必要な、 下位接続に固有の統計の リストとする。

    5. transport.[[NewConnection]] が "no" である場合、 gatheredStats から、プールされた 接続統計としてマークされていないすべての統計を削除する。

    6. transportネットワークタスクをキューに入れ、 次の手順を実行する:

      1. stats を新しい WebTransportConnectionStats オブジェクトとする。

      2. datagramStats を新しい WebTransportDatagramStats オブジェクトとする。

      3. stats["datagrams"] を datagramStats に設定する。

      4. ユーザーエージェントが公開したい stats および datagramStats の各メンバー member について、 membergatheredStats 内の対応する エントリ設定する。

      5. pstats解決する。

  5. p を返す。

exportKeyingMaterial(BufferSource label, BufferSource context, unsigned long outputLength)

この WebTransport下位接続に一意に関連付けられた TLS セッションについて、 TLS Keying Material Exporter から鍵材料をエクスポートする。 呼び出されたとき、ユーザーエージェントは次の手順を実行しなければならない:

  1. labelLengthlabel.byte length とする。

  2. labelLength が 255 より大きい場合、 RangeError拒否された promiseを返す。

  3. contextLengthcontext.byte length とする。

  4. contextLength が 255 より大きい場合、 RangeError拒否された promiseを返す。

  5. outputLength が 0、または 4096 以上で実装定義の値—​その値は少なくとも 4096 で なければならない—​より大きい場合、 RangeError拒否された promiseを返す。

  6. this.[[State]]"closed" または "failed" である場合、 InvalidStateError拒否された promiseを返す。

  7. transportthis とする。

  8. p を新しい promise とする。

  9. 次の手順を並列に実行する。ただし、transport[[State]]"closed" または "failed" になると 中止し、代わりに pInvalidStateError拒否するため、transportネットワークタスクをキューに入れる

    1. keyingMaterial を、[WEB-TRANSPORT-OVERVIEW] セクション 4.1 で定義されるとおり、labelcontext、および outputLength を用いて TLS 鍵エクスポーターを呼び出すことによって生成される Uint8Array とする。

    2. pkeyingMaterial解決するため、transportネットワークタスクをキューに入れる

  10. p を返す。

createBidirectionalStream(options)

送信用の双方向ストリームのための WebTransportBidirectionalStream オブジェクトを作成する。ストリームを単に作成しただけでは、 データ送信に使用されるまで、ピアにはすぐには見えないことに注意。

注: サーバーは、データがその上で送信されるまで、そのストリームを認識することは期待されない。

呼び出されたとき、ユーザーエージェントは次の手順を実行しなければならない:

  1. sendGroupoptionssendGroup とする。

  2. sendGroup が null でなく、かつ sendGroup.[[Transport]]this でない場合、 TypeError拒否された promiseを返す。

  3. this.[[State]]"closed" または "failed" である場合、 InvalidStateError拒否された promiseを返す。

  4. sendOrderoptionssendOrder とする。

  5. waitUntilAvailableoptionswaitUntilAvailable とする。

  6. p を新しい promise とする。

  7. transportthis とする。

  8. 次の手順を並列に実行する。ただし、transport[[State]]"closed" または "failed" になると 中止し、代わりに pInvalidStateError拒否するため、transportネットワークタスクをキューに入れる

    1. streamId を、[QUIC] セクション 19.11で定義されるとおり、 transport.[[Session]] に対して有効かつ一意である新しいストリーム ID とする。枯渇によりそれが すぐに利用可能でない場合、waitUntilAvailable が true なら利用可能になるまで待ち、 waitUntilAvailable が false なら、 p を、requestedquota がどちらも null である QuotaExceededError拒否するため、transportネットワークタスクをキューに入れた後、 これらの手順を中止する。

    2. internalStream を、 transport.[[Session]]streamId を用いて双方向 ストリームを作成する結果とする。

    3. transportネットワークタスクをキューに入れ、 次の手順を実行する:

      1. transport.[[State]]"closed" または "failed" である場合、 pInvalidStateError拒否し、 これらの手順を中止する。

      2. stream を、 internalStreamtransportsendGroup、および sendOrder を用いて WebTransportBidirectionalStream作成する結果とする。

      3. pstream解決する。

  9. p を返す。

createUnidirectionalStream(options)

送信用の単方向ストリームのための WebTransportSendStream を作成する。ストリームを単に作成しただけでは、データ送信に使用されるまで、 サーバーにはすぐには見えないことに注意。

注: サーバーは、データがその上で送信されるまで、そのストリームを認識することは期待されない。

呼び出されたとき、ユーザーエージェントは次の手順を実行しなければならない:

  1. sendGroupoptionssendGroup とする。

  2. sendGroup が null でなく、かつ sendGroup.[[Transport]]this でない場合、 TypeError拒否された promiseを返す。

  3. this.[[State]]"closed" または "failed" である場合、 InvalidStateError拒否された promiseを返す。

  4. sendOrderoptionssendOrder とする。

  5. waitUntilAvailableoptionswaitUntilAvailable とする。

  6. p を新しい promise とする。

  7. transportthis とする。

  8. 次の手順を並列に実行する。ただし、transport[[State]]"closed" または "failed" になると 中止し、代わりに pInvalidStateError拒否するため、transportネットワークタスクをキューに入れる

    1. streamId を、[QUIC] セクション 19.11で定義されるとおり、 transport.[[Session]] に対して有効かつ一意である新しいストリーム ID とする。枯渇によりそれが すぐに利用可能でない場合、waitUntilAvailable が true なら利用可能になるまで待ち、 waitUntilAvailable が false なら、 pQuotaExceededError拒否するため、transportネットワークタスクをキューに入れた後、 これらの手順を中止する。

    2. internalStream を、 transport.[[Session]]streamId を用いて送信用の 単方向ストリームを作成する結果とする。

    3. transportネットワークタスクをキューに入れ、 次の手順を実行する:

      1. transport.[[State]]"closed" または "failed" である場合、 pInvalidStateError拒否し、 これらの手順を中止する。

      2. stream を、 internalStreamtransportsendGroup、 および sendOrder を用いて WebTransportSendStream作成する結果とする。

      3. pstream解決する。

  9. p を返す。

createSendGroup()

WebTransportSendGroup を作成する。

createSendGroup() メソッドが呼び出されたとき、ユーザーエージェントは 次の手順を実行しなければならない:
  1. this.[[State]]"closed" または "failed" である場合、 InvalidStateError投げる

  2. this を用いて WebTransportSendGroup作成する結果を返す。

6.5. 手順

WebTransport transporterror および 任意で closeInfo を用いてクリーンアップするには、次の手順を実行する:
  1. sendStreamstransport.[[SendStreams]] のコピーとする。

  2. receiveStreamstransport.[[ReceiveStreams]] のコピーとする。

  3. outgoingDatagramWritablestransport.[[Datagrams]].[[Writables]] とする。

  4. incomingDatagramstransport.[[Datagrams]].[[Readable]] とする。

  5. readytransport.[[Ready]] とする。

  6. closedtransport.[[Closed]] とする。

  7. incomingBidirectionalStreamstransport.[[IncomingBidirectionalStreams]] とする。

  8. incomingUnidirectionalStreamstransport.[[IncomingUnidirectionalStreams]] とする。

  9. transport.[[SendStreams]] を空の 集合に設定する。

  10. transport.[[ReceiveStreams]] を空の 集合に設定する。

  11. transport.[[Datagrams]].[[OutgoingDatagramsQueue]] を空の キューに設定する。

  12. transport.[[Datagrams]].[[IncomingDatagramsQueue]] を空の キューに設定する。

  13. closeInfo が与えられている場合、transport.[[State]]"closed" に設定する。 そうでない場合、transport.[[State]]"failed" に設定する。

  14. sendStreams 内の各 stream について 反復し、次の手順を実行する:

    1. stream.[[PendingOperation]] が null でない場合、stream.[[PendingOperation]]error で拒否する。

    2. streamerrorエラーにする

  15. receiveStreams 内の各 stream について 反復しstreamerrorエラーにする

    注:スクリプト作者は、Promise 解決時に 同期的に実行されるコードを挿入できる。したがって ここからは、transport に触れてはならない。スクリプトによって予測不能な形で変更される可能性があるためである。 これは、この手続きを呼び出すロジックにも適用される。

  16. closeInfo が与えられている場合:

    1. closedcloseInfo解決する。

    2. 表明:readysettledしている。

    3. incomingBidirectionalStreams閉じる

    4. incomingUnidirectionalStreams閉じる

    5. outgoingDatagramWritables 内の各 writable について、writable閉じる

    6. incomingDatagrams閉じる

  17. そうでない場合:

    1. closederror拒否する。

    2. closed.[[PromiseIsHandled]] を true に設定する。

    3. readyerror拒否する。

    4. ready.[[PromiseIsHandled]] を true に設定する。

    5. incomingBidirectionalStreamserrorエラーにする

    6. incomingUnidirectionalStreamserrorエラーにする

    7. outgoingDatagramWritables 内の各 writable について、writableerrorエラーにする

    8. incomingDatagramserrorエラーにする

WebTransport transport と一連の手順 steps を用いてネットワークタスクをキューに入れるには、次の手順を実行する:

  1. steps を実行するために、transport関連するグローバルオブジェクトを用いて、 ネットワークタスクソース上で グローバルタスクをキューに入れる

6.6. クライアントによって開始されていないセッション終了

WebTransport transport に関連付けられた WebTransport セッションが、 任意で code および reasonBytes を伴って 終了されたときは常に、 次の手順を実行する:
  1. transportネットワークタスクをキューに入れ、 次の手順を実行する:

    1. transport.[[State]]"closed" または "failed" である場合、これらの手順を中止する。

    2. error を、新たに 作成された WebTransportError とし、その source"session" とする。

    3. closeInfo を新しい WebTransportCloseInfo とする。

    4. code が与えられている場合、closeInfocloseCodecode に設定する。

    5. reasonBytes が与えられている場合、closeInforeason を、reasonBytesUTF-8 復号したものに設定する。

      注:reasonBytes には、 言語または書字方向のメタデータは利用できない。 値を表示するときの書字方向には First-strong ヒューリスティックを 使用できる。

    6. error および closeInfo を用いて transportクリーンアップする。

WebTransport transport下位接続で接続エラーが発生したときは常に、 次の手順を実行する:
  1. transportネットワークタスクをキューに入れ、 次の手順を実行する:

    1. transport.[[State]]"closed" または "failed" である場合、これらの手順を中止する。

    2. error を、新たに 作成された WebTransportError とし、その source"session" とする。

    3. error を用いて transportクリーンアップする。

6.7. コンテキストクリーンアップ手順

この仕様では、コンテキストクリーンアップ手順を以下の手順として定義する。 WebTransport transport が与えられた場合:

  1. transport.[[State]]"connected" である場合:

    1. transport.[[State]]"failed" に設定する。

    2. 並列にtransport.[[Session]]終了する。

    3. transportネットワークタスクをキューに入れ、 次の手順を実行する:

      1. error を、新たに 作成された WebTransportError とし、その source"session" とする。

      2. error を用いて transportクリーンアップする。

  2. transport.[[State]]"connecting" である場合、transport.[[State]]"failed" に設定する。

    これはワーカーでも 行われる必要がある。参照: #127 および whatwg/html#6731

6.8. ガベージコレクション

WebTransport オブジェクトで、その [[State]]"connecting" であるものは、 [[IncomingBidirectionalStreams]][[IncomingUnidirectionalStreams]]、 任意の WebTransportReceiveStream、 または [[Datagrams]].[[Readable]]ロックされている場合、または readydraining、 もしくは closed promise が観測されている場合、ガベージコレクトされてはならない。

WebTransport オブジェクトで、その [[State]]"connected" であるものは、 [[IncomingBidirectionalStreams]][[IncomingUnidirectionalStreams]]、 任意の WebTransportReceiveStream、 または [[Datagrams]].[[Readable]]ロックされている場合、または draining もしくは closed promise が観測されている場合、ガベージコレクトされてはならない。

WebTransport オブジェクトで、その [[State]]"draining" であるものは、 [[IncomingBidirectionalStreams]][[IncomingUnidirectionalStreams]]、 任意の WebTransportReceiveStream、 または [[Datagrams]].[[Readable]]ロックされている場合、または closed promise が観測されている場合、ガベージコレクトされてはならない。

確立された WebTransport セッションを持つ WebTransport オブジェクトで、ネットワークへ送信されるようキューに入れられたデータを持つものは、 [[Datagrams]].[[OutgoingDatagramsQueue]] 内のデータグラムを含め、ガベージコレクトされてはならない。

WebTransport オブジェクトが、下位接続 がまだ開いている間にガベージコレクトされた場合、ユーザーエージェントは Application Error Code 0 および Application Error Message ""WebTransport セッションを終了 しなければならない。

6.9. 設定

dictionary WebTransportHash {
  required DOMString algorithm;
  required BufferSource value;
};

dictionary WebTransportOptions {
  boolean allowPooling = false;
  boolean requireUnreliable = false;
  HeadersInit headers = {};
  sequence<WebTransportHash> serverCertificateHashes = [];
  WebTransportCongestionControl congestionControl = "default";
  [EnforceRange] unsigned short? anticipatedConcurrentIncomingUnidirectionalStreams = null;
  [EnforceRange] unsigned short? anticipatedConcurrentIncomingBidirectionalStreams = null;
  sequence<DOMString> protocols = [];
  ReadableStreamType datagramsReadableType;
};

enum WebTransportCongestionControl {
  "default",
  "throughput",
  "low-latency",
};

WebTransportOptions は、 WebTransport セッションの確立方法や利用方法を決定するパラメータを持つ辞書型です。

allowPooling boolean 型、初期値は false

true に設定すると、WebTransport セッションはプーリング可能(他の WebTransport セッションと 基盤コネクション を共有可能)になります。

requireUnreliable boolean 型、初期値は false

true に設定すると、WebTransport セッション は HTTP/2 の connection では確立できなくなり、 HTTP/3 の connection が不可能な場合は失敗します。

headers HeadersInit 型、初期値は {}

オプションで、Headers オブジェクトやオブジェクトリテラル、二要素配列の配列として指定可能。 request の header list は、この値で セッション確立 時に利用される。

serverCertificateHashes sequence<WebTransportHash> 型、初期値 []

このオプションがサポートされるのは専用接続(dedicated connection)の場合のみです。 この機能をサポートしないトランスポートプロトコルの場合、 このフィールドが空でなければ NotSupportedError 例外をスローします。

サポートされ、かつ空でない場合、ユーザーエージェントは 証明書ハッシュ検証serverCertificateHashes に対して成功し、カスタム証明書要件も満たす場合のみ、サーバー証明書を信頼するものとします。 ユーザーエージェントは未知の algorithm を使ったハッシュを無視します。  の場合、通常の fetch 操作と同じ証明書検証手続きを使います。

これは allowPooling との併用は不可です。

congestionControl WebTransportCongestionControl 型、 初期値 "default"

オプションで、アプリケーションがスループット最適化または低遅延に特化した輻輳制御アルゴリズムを希望する場合に指定。 この値はユーザーエージェントへのヒントとなります。

この設定オプションはブラウザで低遅延向け輻輳制御アルゴリズムが実装されていないため危険扱い(at risk)です。

anticipatedConcurrentIncomingUnidirectionalStreams unsigned short 型、nullable、初期値 null

オプションで、アプリケーションがサーバーにより同時生成される 受信単方向ストリーム数を指定できます。 ユーザーエージェントは、サーバーから最低100の 受信単方向 ストリームを初期状態で許可します。 nullでない場合、ラウンドトリップ削減のため [[AnticipatedConcurrentIncomingUnidirectionalStreams]] をサーバーとの協議時に考慮しようとします。

anticipatedConcurrentIncomingBidirectionalStreams unsigned short 型、nullable、初期値 null

オプションで、アプリケーションがサーバーにより同時生成される 双方向ストリーム数を指定できます。 ユーザーエージェントは、サーバーが最低100の 双方向ストリームを生成可能とします。 nullでない場合、ラウンドトリップ削減のため [[AnticipatedConcurrentIncomingBidirectionalStreams]] をサーバーとの協議時に考慮しようとします。

protocols sequence<DOMString> 型、初期値 []

アプリケーションレベルの プロトコル名配列(オプション)。 サーバー側は推奨プロトコルを選択してクライアントに通知するか任意。適切なプロトコルが指定されなかった場合リクエスト拒否もあり得ます。

datagramsReadableType ReadableStreamType

オプションで、受信データグラム用の readable byte stream を使いたい場合に指定。 未指定ならデフォルトの readable stream が用いられます。

注記: readable stream はデータグラムの意味論と互換性がありますが、 readable byte stream はそうではありません。データグラムは意味のあるメッセージ(0以上バイト)で順不同に到達するため、単なるバイト列とは異なります。 空のデータグラムは失われますし、 min ではメッセージの区切りが失われます。

証明書ハッシュを計算するために、certificate を与え、次の手順を実行する:

  1. certcertificate とし、[RFC5280] で定義される Certificate メッセージの DER エンコーディングとして表現する。

  2. cert の SHA-256 ハッシュを計算し、計算された値を返す。

証明書ハッシュを検証するために、certificate chain とハッシュ配列 hashes を与え、次の手順を実行する:

  1. certificatecertificate chain の最初の証明書(リーフ証明書)とする。

  2. referenceHash を、certificate を用いて証明書ハッシュを計算した結果とする。

  3. hashes 内のすべてのハッシュ hash について:

    1. もし hash.value が null でなく、かつ hash.algorithm が "sha-256" とASCII 大文字小文字非区別で一致するなら:

      1. hashValue を、hash.value が表すバイト列とする。

      2. もし hashValuereferenceHash に等しいなら、true を返す。

  4. false を返す。

カスタム 証明書要件は次のとおりである: 証明書は [RFC5280] で定義される X.509v3 証明書でなければならず、 Subject Public Key フィールドで使用される鍵は、許可される公開鍵アルゴリズムのいずれかでなければならず、 現在時刻は [RFC5280] の Section 4.1.2.5 で定義される証明書の有効期間内でなければならず、 かつ有効期間の合計の長さは 2 週間を超えてはならない。ユーザーエージェントは、その証明書に追加の 実装定義要件を課してもよい。

Subject Public Key Info フィールド(およびその結果として TLS CertificateVerify メッセージ)で使用される許可される公開鍵アルゴリズムの正確な一覧は 実装定義である。ただし、相互運用可能な既定値を提供するため、 secp256r1(NIST P-256)名前付きグループを持つ ECDSA([RFC3279], Section 2.3.5; [RFC8422]) を含まなければならない。RSA 鍵を含んではならない ([RFC3279], Section 2.3.1)。

6.10. WebTransportCloseInfo辞書

WebTransportCloseInfo 辞書は、 WebTransport セッション終了する際に、エラーコードと理由を設定するために使用される 情報を含む。

dictionary WebTransportCloseInfo {
  unsigned long closeCode = 0;
  USVString reason = "";
};

この辞書は次の属性を持つものとする:

closeCode, 型は unsigned long、既定値は 0

ピアに伝達されるエラーコード。

reason, 型は USVString、既定値は ""

WebTransport を閉じる理由。

6.11. WebTransportSendOptions辞書

WebTransportSendOptionsは、 createUnidirectionalStreamcreateBidirectionalStreamcreateWritable の振る舞いに影響を与える基本パラメータの辞書です。

dictionary WebTransportSendOptions {
  WebTransportSendGroup? sendGroup = null;
  long long sendOrder = 0;
};

この辞書は次の属性を持ちます:

sendGroup, WebTransportSendGroup、null可能、デフォルトはnull

作成されたストリームをグループ化するための任意のWebTransportSendGroup、またはnull。

sendOrder, long long、デフォルトは0

送信順序番号。指定すると作成されたストリームは厳密な順序付けに参加します。 現在厳密順序ストリームにキューされたバイトは、より小さい送信順序番号で作成された他の厳密順序ストリームにキューされたバイトよりも先に送信されます。

送信順序番号が指定されていない場合、他のストリームとの相対的な送信順は実装定義です。ただし、ユーザーエージェントは、低い順序番号で飢餓状態になっていない限り、すべてのストリーム間で帯域を公平に分配することが強く推奨されます。

注: これは送信側のデータ優先制御であり、受信順序を保証するものではありません。

6.12. WebTransportSendStreamOptions辞書

WebTransportSendStreamOptionsは、 WebTransportSendStreamの パラメータ辞書であり、 createUnidirectionalStream および createBidirectionalStream で生成されたストリームの振る舞いに影響します。

dictionary WebTransportSendStreamOptions : WebTransportSendOptions {
  boolean waitUntilAvailable = false;
};

この辞書は次の属性を持ちます:

waitUntilAvailable, 型は boolean、既定値は false

true の場合、 createUnidirectionalStream または createBidirectionalStream 呼び出しによって返される promise は、下位接続がストリームを作成するのに十分なフロー制御 クレジットを持つか、またはその接続が以後の送信用ストリームを 作成できない状態に到達するまで、settled されない。false の場合、呼び出し時点で利用可能なフロー制御ウィンドウがなければ、 promise は拒否される。

6.13. WebTransportConnectionStats辞書

WebTransportConnectionStats 辞書は、 WebTransport セッション基礎となる接続に関する情報を含む。 WebTransportConnectionStats のメンバーのうち、 プールされた接続 統計としてマークされていないものは、プーリングの対象となる 基礎となる 接続では存在しない

注: プーリングが許可されている場合、プールされた 接続統計のみが公開され、 同じ接続上でプールされた複数の WebTransport セッションはすべて同じ情報を受け取る。 すなわち、その情報は同じ ネットワーク分割キーを保持する、 プールされたセッション間で開示される。

注: 利用できない統計はすべて、WebTransportConnectionStats 辞書から存在しないものとなる。

dictionary WebTransportConnectionStats {
  unsigned long long bytesSent;
  unsigned long long bytesSentOverhead;
  unsigned long long bytesAcknowledged;
  unsigned long long packetsSent;
  unsigned long long bytesLost;
  unsigned long long packetsLost;
  unsigned long long bytesReceived;
  unsigned long long packetsReceived;
  DOMHighResTimeStamp smoothedRtt;
  DOMHighResTimeStamp rttVariation;
  DOMHighResTimeStamp minRtt;
  required WebTransportDatagramStats datagrams;
  unsigned long long? estimatedSendRate = null;
  boolean atSendCapacity = false;
};

この辞書は次の属性を持つものとする:

bytesSent, 型は unsigned long long

基礎となる接続上で送信されたペイロードバイト数。 フレーミングのオーバーヘッドまたは再送は含まない。

bytesSentOverhead, 型は unsigned long long

基礎となる接続上で bytesSent 個のペイロードバイトを送信する際の、フレーミングおよび再送のオーバーヘッドのバイト数。

bytesAcknowledged, 型は unsigned long long

基礎となる接続上で、QUIC の ACK メカニズムを使用して サーバーに受信済みとして確認応答されたペイロードバイト数。フレーミングは含まない。

注: 通常は bytesSent に遅れるが、パケット損失により永続的に少なくなることがある。

bytesAcknowledged on WebTransportConnectionStats は、実装可能性への懸念により、ワーキンググループによって リスクのある機能として特定されている。
packetsSent, 型は unsigned long long

基礎となる接続上で送信されたパケット数。 損失したと判定されたものを含む。

bytesLost, 型は unsigned long long

基礎となる接続上で失われたバイト数(単調増加しない。 これは、損失と宣言されたパケットが後で受信されることがあるためである)。 UDP またはその他の外側のフレーミングは含まない。

packetsLost, 型は unsigned long long

基礎となる接続上で失われたパケット数(単調増加しない。 これは、損失と宣言されたパケットが後で受信されることがあるためである)。

bytesReceived, 型は unsigned long long

基礎となる接続上で受信された総バイト数。 ストリームの重複データを含む。UDP またはその他の外側のフレーミングは含まない。

packetsReceived, 型は unsigned long long

基礎となる接続上で受信された総パケット数。 処理できなかったパケットを含む。

smoothedRtt, 型は DOMHighResTimeStamp

[RFC9002] Section 5.3 で定義される、 接続上で現在観測されている平滑化された往復時間(RTT)。 これはプールされた接続統計である。

rttVariation, 型は DOMHighResTimeStamp

[RFC9002] Section 5.3 で定義される、 接続上で現在観測されている往復時間サンプルの平均変動。 これはプールされた接続統計である。

minRtt, 型は DOMHighResTimeStamp

[RFC9002] Section 5.2 で定義される、 接続全体で観測された最小往復時間。 これはプールされた接続統計である。

estimatedSendRate, 型は unsigned long long、nullable、既定値は null

キューに入れられたデータがユーザーエージェントによって送信される推定速度。単位はビット毎秒である。 この速度は、WebTransport セッションを共有するすべてのストリームおよびデータグラムに適用され、 (congestionControl によって選択される可能性のある) 輻輳制御アルゴリズムによって計算される。 この推定値はフレーミングのオーバーヘッドを除外し、 アプリケーションペイロードが送信されうる速度を表す。ユーザーエージェントが 現在推定値を持っていない場合、このメンバーは null 値でなければならない。 このメンバーは、以前の結果で null でなかった場合でも null になりうる。 これはプールされた接続統計である。

atSendCapacity, 型は boolean、既定値は false

false の値は、estimatedSendRate がアプリケーションに制限されている可能性を示す。 これは、アプリケーションが輻輳制御器の許す量よりも大幅に少ないデータを送信していることを意味する。 輻輳制御器は、アプリケーションに制限されている間、利用可能なネットワーク容量について 不十分な推定値を生成することがある。

true の値は、アプリケーションがネットワーク 容量でデータを送信しており、estimatedSendRate がアプリケーションに利用可能なネットワーク容量を 反映していることを示す。

atSendCapacitytrue の場合、estimatedSendRate は上限を反映する。 アプリケーションの送信速度が維持されている限り、estimatedSendRate はネットワーク状況に適応する。しかし、estimatedSendRate は、atSendCapacity が true である間も null であることが許される。
これはプールされた接続統計である。

6.14. WebTransportDatagramStats辞書

WebTransportDatagramStats 辞書には 基盤コネクション 上のデータグラム送受信に関する統計が含まれる。

dictionary WebTransportDatagramStats {
  unsigned long long droppedIncoming;
  unsigned long long expiredIncoming;
  unsigned long long expiredOutgoing;
  unsigned long long lostOutgoing;
};

この辞書は以下の属性を持つものとする:

droppedIncoming, unsigned long long

アプリケーションがdatagramsreadable から読み出す前に、受信キューが新しいデータグラムであふれてしまったために廃棄された受信データグラムの数。

expiredIncoming, unsigned long long

incomingMaxAge よりも古くなったため、datagramsreadable から読み出される前に廃棄された受信データグラムの数。

expiredOutgoing, unsigned long long

送信待ちキュー内のデータグラムがoutgoingMaxAge よりも古くなったため送信される前に廃棄された数。

lostOutgoing, unsigned long long

送信済みデータグラムのうちロスト([RFC9002] Section 6.1参照)と判定された数。

7. インターフェイス WebTransportSendStream

WebTransportSendStream は、送信単方向または双方向WebTransportストリームを使った送信ストリーミング機能を提供する WritableStream です。

これはサーバーにデータを送信するために書き込み可能な WritableStream 型のUint8Array です。

[Exposed=(Window,Worker), SecureContext, Transferable]
interface WebTransportSendStream : WritableStream {
  attribute WebTransportSendGroup? sendGroup;
  attribute long long sendOrder;
  Promise<WebTransportSendStreamStats> getStats();
  WebTransportWriter getWriter();
};

WebTransportSendStream は必ずcreate手続きによって作成されます。

WebTransportSendStream転送ステップおよび 転送受信ステップWritableStreamのものです。

7.1. 属性

sendGroup, 型は WebTransportSendGroup、null 許容

取得子の手順は次のとおり:

  1. this[[SendGroup]] を返す。

value が与えられたときの設定子の手順は次のとおり:

  1. value が null でなく、かつ value.[[Transport]]this.[[Transport]] でない場合、 InvalidStateError投げる

  2. this.[[SendGroup]]value に設定する。

sendOrder, 型は long long

取得子の手順は次のとおり:

  1. this[[SendOrder]] を返す。

value が与えられたときの設定子の手順は次のとおり:

  1. this.[[SendOrder]]value に設定する。

7.2. メソッド

getStats()

この WebTransportSendStream の 性能に固有の統計を収集し、 結果を非同期に報告する。

呼び出されたとき、ユーザーエージェントは次の手順を実行しなければならない:

  1. transportthis.[[Transport]] とする。

  2. p を新しい promise とする。

  3. 次の手順を並列に実行する:

    1. gatheredStats を、 WebTransportSendStreamStats辞書メンバーを正確に埋めるために必要な、 this WebTransportSendStream に固有の統計の リストとする。

    2. transportネットワークタスクをキューに入れ、 次の手順を実行する:

      1. stats を新しい WebTransportSendStreamStats オブジェクトとする。

      2. ユーザーエージェントが公開したい stats の各メンバー member について、 membergatheredStats 内の対応する エントリ設定する。

      3. pstats解決する。

  4. p を返す。

getWriter()

this ストリーム用の WebTransportWriter を作成する。

getWriter が呼び出されたとき、 this を用いて WebTransportWriter作成する結果を返す。

7.3. 内部スロット

WebTransportSendStream は以下の内部スロットを持つ。

内部スロット 説明 (参考)
[[InternalStream]] 送信単方向 または 双方向 WebTransport ストリーム
[[PendingOperation]] 進行中の書き込みまたはクローズ操作を表す promise、または null。
[[Transport]] この WebTransport に 所有される WebTransportSendStream
[[SendGroup]] オプションの WebTransportSendGroup、 または null。
[[SendOrder]] 省略時は 0 となる送信順番号(オプション)。
[[AtomicWriteRequests]] 順序付き集合としての promise 群で、 下層シンクにキューされた書き込みリクエストのうち アトミックなものだけ追跡する。
[[InsideSynchronousAtomicWrite]] atomicWrite メソッドの 同期部分の間のみ true となるブール値。
[[BytesWritten]] ストリームに書き込まれたバイト数。
[[CommittedOffset]] ストリームのオフセット値。 送信が中断 しても、ピアに配送されるバイト数を記録するための オフセット値。 [RELIABLE-RESET] を参照。

7.4. 手続き

作成するには、 WebTransportSendStream を、送信単方向または双方向 WebTransportストリーム internalStreamWebTransport transportsendGroupsendOrderを指定し、次の手順を実行する:

  1. stream新しい WebTransportSendStream として次のように初期化する:

    [[InternalStream]]

    internalStream

    [[PendingOperation]]

    null

    [[Transport]]

    transport

    [[SendGroup]]

    sendGroup

    [[SendOrder]]

    sendOrder

    [[AtomicWriteRequests]]

    空の順序付き集合のpromise

    [[InsideSynchronousAtomicWrite]]

    false

    [[BytesWritten]]

    0

    [[CommittedOffset]]

    0

  2. writeAlgorithmwrite chunkstream に書き込むアクション(chunkを指定)とする。

  3. closeAlgorithmclose stream とするアクションとする。

  4. abortAlgorithmabort reason を指定して stream を中断するアクションとする。

  5. セットアップ stream に、 writeAlgorithmwriteAlgorithm に、 closeAlgorithmcloseAlgorithm に、 abortAlgorithmabortAlgorithm に設定して実行する。

  6. abortSignalstream の [[controller]].[[abortController]].[[signal]] とする。

  7. Add 以下の手順を abortSignal に追加する:

    1. pendingOperationstream.[[PendingOperation]] とする。

    2. pendingOperation が null ならこれ以降中止。

    3. stream.[[PendingOperation]] を null に設定。

    4. reasonabortSignalabort reasonとする。

    5. promiseabort streamreason を指定した結果とする。

    6. fulfillment時promise がresolveされたら reject pendingOperationreason で返す。

  8. append streamtransport.[[SendStreams]] に追加する。

  9. stream を返す。

chunkWebTransportSendStream stream書き込むには、次の手順を実行する:
  1. transportstream.[[Transport]] とする。

  2. chunkBufferSource でない場合、 TypeError拒否された promiseを返す。

  3. promise を新しい promise とする。

  4. bytes を、chunk が表す バイト シーケンスのコピーとする。

  5. bytes長さが 0 である場合、 promise を undefined で解決し、 promise を返す。

  6. stream.[[PendingOperation]]promise に設定する。

  7. inFlightWriteRequeststream.inFlightWriteRequest とする。

  8. atomic を、stream.[[AtomicWriteRequests]]inFlightWriteRequest含むか、または stream.[[InsideSynchronousAtomicWrite]] が true である場合は true、そうでなければ false とする。

  9. 次の手順を並列に実行する:

    1. atomic が true であり、現在のフロー 制御ウィンドウが、bytes を全体として送信するには小さすぎる場合、 残りの手順を中止し、transportネットワークタスクをキューに入れ、 次の副手順を実行する:

      1. stream.[[PendingOperation]] を null に設定する。

      2. stream 上のすべての アトミック書き込みリクエストを中止する。

    2. そうでない場合、stream.[[InternalStream]] 上で bytes送信し、 その操作の完了を待つ。 この送信は送信順序規則に従わなければならない。

      ユーザーエージェントは、転送性能を向上させるためにバッファを持ってもよい。そのようなバッファは、 WebTransportSendStream の利用者へバックプレッシャー情報を伝えるため、固定された上限を持つべきである。

      ここでは stream.[[SendOrder]]並列にアクセスする。 ユーザーエージェントは送信中、これらの値のライブ更新に応答するべきであるが、 詳細は実装定義である。

      注:再送信の順序付けは 実装定義であるが、 ユーザーエージェントには、より高い [[SendOrder]] 値を持つデータの再送信を優先することが強く推奨される。

      この送信は、フロー制御上の理由またはエラーを除き、 他の送信を飢餓状態にしてはならない。

      ユーザーエージェントは、飢餓状態でないすべてのストリーム間で帯域幅を公平に分割するべきである。

      注:ここでの公平性の定義は 実装定義である。

    3. 前の手順がネットワークエラーにより失敗した場合、残りの手順を中止する。

      注:ここでは promise を拒否しない。これは、ネットワークエラーを別の箇所で処理し、 それらの手順が stream.[[PendingOperation]] を拒否するためである。

    4. そうでない場合、transportネットワークタスクをキューに入れ、 次の手順を実行する:

      1. stream.[[PendingOperation]] を null に設定する。

      2. bytes の長さを stream.[[BytesWritten]] に加算する。

      3. stream.[[AtomicWriteRequests]]inFlightWriteRequest含む場合、inFlightWriteRequest削除する。

      4. promise を undefined で解決する。

  10. promise を返す。

注:このアルゴリズム(または write(chunk)) から返される promise の履行は、 その chunk がサーバーによって ack されたことを必ずしも意味しない [QUIC]。単にその chunk がバッファに追加されたことを意味するだけの場合がある。 chunk がサーバーに到達したことを確認するには、サーバーがアプリケーションレベルの確認応答メッセージを送る必要がある。

WebTransportSendStream stream閉じるには、次の手順を実行する:
  1. transportstream.[[Transport]] とする。

  2. promise を新しい promise とする。

  3. streamtransport.[[SendStreams]] から削除する。

  4. stream.[[PendingOperation]]promise に設定する。

  5. 次の手順を並列に実行する:

    1. stream.[[InternalStream]] 上で FIN を送信し、 その操作の完了を待つ。

    2. stream.[[InternalStream]] が「すべてのデータがコミット済み」状態に入るまで待つ。[QUIC]

    3. transportネットワークタスクをキューに入れ、 次の手順を実行する:

      1. stream.[[PendingOperation]] を null に設定する。

      2. promise を undefined で解決する。

  6. promise を返す。

WebTransportSendStream streamreason中止するには、次の手順を実行する:
  1. transportstream.[[Transport]] とする。

  2. promise を新しい promise とする。

  3. code を 0 とする。

  4. streamtransport.[[SendStreams]] から削除する。

  5. reasonWebTransportError であり、かつ reason.[[StreamErrorCode]] が null でない場合、codereason.[[StreamErrorCode]] に設定する。

  6. code < 0 の場合、code を 0 に設定する。

  7. code > 4294967295 の場合、code を 4294967295 に設定する。

  8. committedOffsetstream.[[CommittedOffset]] とする。

    注:code の有効な値は 0 から 4294967295 まで(両端を含む)である。下位接続が HTTP/3 を使用している場合、その code は [WEB-TRANSPORT-HTTP3] に記述されているように、[0x52e4a40fa8db, 0x52e5ac983162] 内の数値へ符号化される。

  9. 次の手順を並列に実行する:

    1. code および committedOffset を用いて、 stream.[[InternalStream]] 上の送信を中止する。

    2. promise を undefined で解決するため、 transportネットワークタスクをキューに入れる

  10. promise を返す。

WebTransportSendStream stream 上のすべてのアトミック書き込みリクエストを中止するには、 次の手順を実行する:
  1. writeRequestsstream.writeRequests とする。

  2. requestsToAbortstream.[[AtomicWriteRequests]] とする。

  3. writeRequests が、requestsToAbort 内にない promise を含む場合、 AbortError を用いて streamエラーにし、 これらの手順を中止する。

  4. stream.[[AtomicWriteRequests]]空にする

  5. requestsToAbort 内の各 promise について反復しpromiseAbortError拒否する。

  6. 並列にrequestsToAbort 内の各 promise について反復しpromise に関連付けられたバイトの 送信を中止する。

7.5. サーバーから送信された受信中止シグナルの受信

WebTransportSendStream stream に関連付けられた WebTransport ストリームが、サーバーから 受信中止シグナルを受け取ったときは常に、次の 手順を実行する:
  1. transportstream.[[Transport]] とする。

  2. code を、受信中止シグナルに付加されたアプリケーションプロトコルエラーコードとする。

    注:code の有効な値は 0 から 4294967295 まで(両端を含む)である。下位接続が HTTP/3 を使用している場合、その code は [WEB-TRANSPORT-HTTP3] に記述されているように、[0x52e4a40fa8db, 0x52e5ac983162] 内の数値へ符号化される。

  3. transportネットワークタスクをキューに入れ、 次の手順を実行する:

    1. transport.[[State]]"closed" または "failed" である場合、これらの手順を中止する。

    2. streamtransport.[[SendStreams]] から削除する。

    3. error を、新たに 作成された WebTransportError とし、その source"stream" であり、 streamErrorCodecode であるものとする。

    4. stream.[[PendingOperation]] が null でない場合、stream.[[PendingOperation]]error で拒否する。

    5. streamerrorエラーにする

7.6. WebTransportSendStreamStats辞書

WebTransportSendStreamStats辞書には、 1つのWebTransportSendStream に特有の統計情報が含まれます。

dictionary WebTransportSendStreamStats {
  unsigned long long bytesWritten;
  unsigned long long bytesSent;
  unsigned long long bytesAcknowledged;
};

この辞書は以下の属性を持つものとする:

bytesWritten, unsigned long long

アプリケーションがこの WebTransportSendStream に正常に書き込んだバイト数の合計。この値は増加のみ行われる。

bytesSent, unsigned long long

この WebTransportSendStream に書き込み済みのアプリケーションバイトのうち、少なくとも一度は送信されたものの進捗を示す指標。この値は増加のみ行われ、常に bytesWritten 以下となる。

Note: これは単一ストリームで送信されたアプリデータの進捗のみを示し、ネットワークのオーバーヘッドは含まない。

bytesAcknowledged, unsigned long long

この WebTransportSendStream に書き込み済みのアプリケーションバイトがサーバのQUIC ACK機構で送信・受信確認されたバイトの進捗指標。最初の未確認バイト未満までの連続したバイトのみをカウント。この値は増加のみ行われ、常に bytesSent 以下となる。

Note: この値はコネクションがHTTP/2の場合、 bytesSent と一致する。

8. インターフェイス WebTransportSendGroup

WebTransportSendGroup は多数の個別(通常は厳密順序WebTransportSendStream にまたがるデータ転送を追跡するためのオプションの管理オブジェクトです。

WebTransportSendStreamWebTransportDatagramsWritable は、 作成時または sendGroup 属性の割り当てによって、任意の時点で最大1つの WebTransportSendGroup または null sendGroup の下でグループ化されます。 デフォルトでは、WebTransportSendStreamWebTransportDatagramsWritablenull sendGroup に割り当てられます。

ユーザーエージェントは、WebTransportSendGroup を 帯域分配時にWebTransportSendStreamへの送信について平等に扱います。 また、各 WebTransportSendGroupsendOrder 番号評価用の独立した数値空間も確立します。

[Exposed=(Window,Worker), SecureContext]
interface WebTransportSendGroup {
  Promise<WebTransportSendStreamStats> getStats();
};

WebTransportSendGroup は必ずcreate手続きによって作成されます。

8.1. メソッド

getStats()

this sendGroup の下にグループ化されたすべての WebTransportSendStream から統計を集約し、その結果を非同期に報告する。

呼び出されたとき、ユーザーエージェントは次の手順を実行しなければならない:

  1. transportthis.[[Transport]] とする。

  2. p を新しい promise とする。

  3. streams を、その [[SendGroup]]this であるすべての WebTransportSendStream とする。

  4. 次の手順を並列に実行する:

    1. gatheredStats を、 WebTransportSendStreamStats辞書メンバーを正確に埋めるために必要な、 streams 内のすべてのストリームから集約された統計の リストとする。

    2. transportネットワークタスクをキューに入れ、 次の手順を実行する:

      1. stats を新しい WebTransportSendStreamStats オブジェクトとする。

      2. ユーザーエージェントが公開したい stats の各メンバー member について、 membergatheredStats 内の対応する エントリ設定する。

      3. pstats解決する。

  5. p を返す。

8.2. 内部スロット

WebTransportSendGroup は以下の内部スロットを持つ。

内部スロット 説明 (非規範的)
[[Transport]] この WebTransport オブジェクトが所有する WebTransportSendGroup

8.3. 手続き

SendGroup を作成するには、 WebTransportSendGroupWebTransport transport を用いて、以下の手順を実行する:

  1. sendGroup新しい WebTransportSendGroup とし、次のように初期化する:

    [[Transport]]

    transport

  2. sendGroup を返す。

9. インターフェイス WebTransportReceiveStream

WebTransportReceiveStream は、受信単方向または双方向WebTransportストリームを用いて、受信ストリーミング機能を提供する ReadableStream です。

これはサーバーから受信したデータを消費するために読み取ることができる ReadableStream 型のUint8Array です。WebTransportReceiveStream読み取りバイトストリームであり、 利用者はBYOBリーダーだけでなくデフォルトリーダーも使用できます。

[Exposed=(Window,Worker), SecureContext, Transferable]
interface WebTransportReceiveStream : ReadableStream {
  Promise<WebTransportReceiveStreamStats> getStats();
};

WebTransportReceiveStream は必ずcreate手続きによって作成されます。

WebTransportReceiveStream転送ステップおよび 転送受信ステップReadableStreamのものです。

9.1. メソッド

getStats()

この WebTransportReceiveStream の 性能に固有の統計を収集し、 結果を非同期に報告する。

呼び出されたとき、ユーザーエージェントは次の手順を実行しなければならない:

  1. transportthis.[[Transport]] とする。

  2. p を新しい promise とする。

  3. 次の手順を並列に実行する:

    1. gatheredStats を、 WebTransportReceiveStreamStats辞書メンバーを正確に埋めるために必要な、 this WebTransportReceiveStream に固有の統計の リストとする。

    2. transportネットワークタスクをキューに入れ、 次の手順を実行する:

      1. stats を新しい WebTransportReceiveStreamStats オブジェクトとする。

      2. ユーザーエージェントが公開したい stats の各メンバー member について、 membergatheredStats 内の対応する エントリ設定する。

      3. pstats解決する。

  4. p を返す。

9.2. 内部スロット

WebTransportReceiveStream には以下の内部スロットがあります。

内部スロット 説明 (参考)
[[InternalStream]] 着信単方向または 双方向 WebTransport ストリーム
[[Transport]] この WebTransport オブジェクトが所有する WebTransportReceiveStream

9.3. 手続き

受信用単方向または双方向WebTransport ストリーム internalStream と、WebTransport transport を用いて、 WebTransportReceiveStream作成するには、次の手順を実行する:

  1. stream を、次を持つ新しい WebTransportReceiveStream とする:

    [[InternalStream]]

    internalStream

    [[Transport]]

    transport

  2. pullAlgorithm を、stream からバイトをプルする動作とする。

  3. cancelAlgorithm を、reason が与えられたときに reasonstreamキャンセルする動作とする。

  4. streamバイト読み取りサポート付きで セットアップし、 pullAlgorithmpullAlgorithm に設定し、 cancelAlgorithmcancelAlgorithm に設定する。

  5. streamtransport.[[ReceiveStreams]]追加する。

  6. stream を返す。

WebTransportReceiveStream stream からバイトをプルするには、次の手順を実行する。

  1. transportstream.[[Transport]] とする。

  2. internalStreamstream.[[InternalStream]] とする。

  3. promise を新しい promise とする。

  4. bufferoffset、および maxBytes を null とする。

  5. stream に対する stream現在の BYOB リクエストビューが null でない場合:

    1. offsetstream現在の BYOB リクエスト ビュー.[[ByteOffset]] に設定する。

    2. maxBytesstream現在の BYOB リクエスト ビューbyte lengthに設定する。

    3. bufferstream現在の BYOB リクエスト ビュー下位バッファに設定する。

  6. そうでない場合:

    1. offset を 0 に設定する。

    2. maxBytes実装定義のサイズに設定する。

    3. buffer を、maxBytes サイズを持つ新しい ArrayBuffer とする。ArrayBuffer の割り当てに失敗した場合、 RangeError拒否された promiseを返す。

  7. 次の手順を並列に実行する:

    1. internalStream から読み取られたバイトを、 offset のオフセットで buffer に、最大 maxBytes バイトまで書き込む。少なくとも 1 バイトが読み取られるか、 FIN が受信されるまで待つ。read を読み取られたバイト数とし、 hasReceivedFIN を FIN が伴っていたかどうかとする。

      ユーザーエージェントは、転送性能を向上させるためにバッファを持ってもよい。そのようなバッファは、 サーバーにバックプレッシャー情報を伝えるため、固定された上限を持つべきである。

      注:この操作は、 buffer 全体を埋める前に返る場合がある。

    2. 前の手順が失敗した場合、残りの手順を中止する。

      注:ここでは promise を拒否しない。これは、ネットワークエラーを別の箇所で処理し、 それらの手順が streamエラーにし、このプルを待っているすべての read リクエストを拒否するためである。

    3. transportネットワークタスクをキューに入れ、 次の手順を実行する:

      注:上で説明したバッファが、 この手続きが実行されているイベントループで利用可能である場合、 次の手順はただちに実行されることがある。

      1. read > 0 の場合:

        1. view を、bufferoffset、および read を持つ新しい Uint8Array とする。

        2. viewstreamキュー投入する。

      2. hasReceivedFIN が true の場合:

        1. streamtransport.[[ReceiveStreams]] から削除する。

        2. stream閉じる

      3. promise を undefined で解決する。

  8. promise を返す。

WebTransportReceiveStream streamreasonキャンセルするには、次の 手順を実行する。

  1. transportstream.[[Transport]] とする。

  2. internalStreamstream.[[InternalStream]] とする。

  3. promise を新しい promise とする。

  4. code を 0 とする。

  5. reasonWebTransportError であり、かつ reason.[[StreamErrorCode]] が null でない場合、codereason.[[StreamErrorCode]] に設定する。

  6. code < 0 の場合、code を 0 に設定する。

  7. code > 4294967295 の場合、code を 4294967295 に設定する。

    注:code の有効な値は 0 から 4294967295 まで(両端を含む)である。下位接続が HTTP/3 を使用している場合、その code は [WEB-TRANSPORT-HTTP3] に記述されているように、[0x52e4a40fa8db, 0x52e5ac983162] 内の数値へ符号化される。

  8. streamtransport.[[SendStreams]] から削除する。

  9. 次の手順を並列に実行する:

    1. code を用いて internalStream 上の 受信を中止する。

    2. transportネットワークタスクをキューに入れ、 次の手順を実行する:

      注:上で説明したバッファが、 この手続きが実行されているイベントループで利用可能である場合、 次の手順はただちに実行されることがある。

      1. streamtransport.[[ReceiveStreams]] から削除する。

      2. promise を undefined で解決する。

  10. promise を返す。

9.4. サーバーから送信中止シグナルを受信した場合

WebTransportReceiveStream stream に関連付けられた WebTransport ストリームが、サーバーから 送信中止シグナルを受け取ったときは常に、次の手順を実行する:
  1. transportstream.[[Transport]] とする。

  2. code を、送信中止シグナルに付加されたアプリケーションプロトコルエラーコードとする。

    注:code の有効な値は 0 から 4294967295 まで(両端を含む)である。下位接続が HTTP/3 を使用している場合、その code は [WEB-TRANSPORT-HTTP3] に記述されているように、[0x52e4a40fa8db, 0x52e5ac983162] 内の数値へ符号化される。

  3. transportネットワークタスクをキューに入れ、 次の手順を実行する:

    1. transport.[[State]]"closed" または "failed" である場合、これらの手順を中止する。

    2. streamtransport.[[ReceiveStreams]] から削除する。

    3. error を、新たに 作成された WebTransportError とし、その source"stream" であり、 streamErrorCodecode であるものとする。

    4. streamerrorエラーにする

9.5. WebTransportReceiveStreamStats辞書

WebTransportReceiveStreamStats辞書には、 1つのWebTransportReceiveStream に特有の統計情報が含まれます。

dictionary WebTransportReceiveStreamStats {
  unsigned long long bytesReceived;
  unsigned long long bytesRead;
};

この辞書は以下の属性を持ちます:

bytesReceived, unsigned long long

サーバアプリケーションがこの WebTransportReceiveStream に対して送信しようとしたバイトのうち、これまでに受信された進捗を示す指標。 連続している最初の欠損バイト直前までのバイトのみがカウントされる。この値は増加のみ行われる。

Note: これは単一ストリームで受信したアプリデータの進捗のみを示し、ネットワークのオーバーヘッドは含まない。

bytesRead, unsigned long long

アプリケーションがこの WebTransportReceiveStream から正常に読み出したバイトの合計。この値は増加のみ行われ、常に bytesReceived 以下となる。

10. インターフェイス WebTransportBidirectionalStream

[Exposed=(Window,Worker), SecureContext]
interface WebTransportBidirectionalStream {
  readonly attribute WebTransportReceiveStream readable;
  readonly attribute WebTransportSendStream writable;
};

10.1. 内部スロット

WebTransportBidirectionalStream は以下の内部スロットを持ちます。

内部スロット 説明 (非規範的)
[[Readable]] WebTransportReceiveStream
[[Writable]] WebTransportSendStream
[[Transport]] この WebTransport オブジェクトが所有する WebTransportBidirectionalStream

10.2. 属性

readable, 型は WebTransportReceiveStream、読み取り専用

取得子の手順は、this[[Readable]] を返すことである。

writable, 型は WebTransportSendStream、読み取り専用

取得子の手順は、this[[Writable]] を返すことである。

10.3. 手続き

WebTransportBidirectionalStream双方向 WebTransport ストリーム internalStreamWebTransport オブジェクト transportsendOrder でもって作成するには、次の手順を実行する。
  1. readableWebTransportReceiveStream の生成 (引数 internalStream, transport) の結果とする。

  2. writableWebTransportSendStream の生成 (引数 internalStream, transport, sendOrder) の結果とする。

  3. stream新しい WebTransportBidirectionalStream (以下のスロットを持つ)とする:

    [[Readable]]

    readable

    [[Writable]]

    writable

    [[Transport]]

    transport

  4. stream を返す。

11. WebTransportWriter インターフェイス

WebTransportWriterWritableStreamDefaultWriter のサブクラスであり、 2つのメソッドを追加しています。

WebTransportWriter は常に create 手続きによって生成されます。

[Exposed=*, SecureContext]
interface WebTransportWriter : WritableStreamDefaultWriter {
  Promise<undefined> atomicWrite(optional any chunk);
  undefined commit();
};

11.1. メソッド

atomicWrite(chunk)

atomicWrite メソッドは、それに与えられた chunk を、送信時点で現在の フロー制御 ウィンドウ内で全体として送信できなかった場合に拒否する。この挙動は、 フロー制御 デッドロックに敏感なニッチなトランザクション用途を満たすよう設計されている ([RFC9308] セクション 4.4)。

注:atomicWrite は、一部のデータを送信した後でも拒否される可能性がある。これは フロー制御に関してアトミック性を提供するが、他のエラーが発生することもある。 atomicWrite は、データがパケット間で分割されたり、 他のデータとインターリーブされたりすることを防がない。 利用可能なフロー制御クレジットの不足により atomicWrite が失敗したかどうかを知るのは送信側だけである。

注:アトミック書き込みは、 非アトミック書き込みの後ろにキュー投入されている場合、依然としてブロックされることがある。 そのアトミック書き込みが拒否された場合、その時点でその後ろにキュー投入されているものは すべて同様に拒否される。このように拒否された非アトミック書き込みはすべて、 ストリームをエラーにする。したがってアプリケーションには、 常にアトミック書き込みを await することが推奨される。

呼び出されたとき、ユーザーエージェントは次の手順を実行しなければならない:

  1. streamthis.stream とする。

  2. stream が undefined である場合、 TypeError拒否された promiseを返す。

  3. stream.[[InsideSynchronousAtomicWrite]] を true に設定する。

  4. p を、chunkthis書き込む結果とする。

  5. stream.[[InsideSynchronousAtomicWrite]] を false に設定する。

  6. pstream.[[AtomicWriteRequests]]追加する。

  7. 次の手順で p反応する結果を返す:

    1. stream.[[AtomicWriteRequests]]p含む場合、 p削除する。

    2. p が理由 r で拒否された場合、 r拒否された promiseを返す。

    3. undefined を返す。

commit()

commit メソッドはストリームの [[CommittedOffset]] を、そのストリームに書き込んだバイト数 ([[BytesWritten]]) に更新します。 これにより、書き込み中断後(stream の abort による 送信中断)でも そのバイトはピアに確実に配送されます。 この仕組みは [RELIABLE-RESET] で解説されています。

注記: これは接続障害時の配送は保証せず、 ストリームの 送信中断 時のみ保証します。

commitstream で呼ばれた時、ユーザーエージェントは次を実行する:

  1. stream.[[CommittedOffset]]stream.[[BytesWritten]] の値に更新する。

11.2. 手続き

WebTransportWriter を、 WebTransportWriterWebTransportSendStream stream でもって作成するには、次の手順を実行する:

  1. writer新しい WebTransportWriter とする。

  2. stream 用に writer設定する

  3. writer を返す。

12. WebTransportError インターフェイス

WebTransportErrorDOMException のサブクラスであり、

[Exposed=(Window,Worker), Serializable, SecureContext]
interface WebTransportError : DOMException {
  constructor(optional DOMString message = "", optional WebTransportErrorOptions options = {});

  readonly attribute WebTransportErrorSource source;
  readonly attribute unsigned long? streamErrorCode;
};

dictionary WebTransportErrorOptions {
  WebTransportErrorSource source = "stream";
  [Clamp] unsigned long? streamErrorCode = null;
};

enum WebTransportErrorSource {
  "stream",
  "session",
};

12.1. 内部スロット

WebTransportError は以下の内部スロットを持ちます。

内部スロット 説明 (非規範的)
[[Source]] WebTransportErrorSource このエラーのソースを示します。
[[StreamErrorCode]] このエラーのアプリケーションプロトコルエラーコード、またはnull。

12.2. コンストラクタ

new WebTransportError(message, options) コンストラクタ手順:

  1. thisname"WebTransportError" に設定する。

  2. thismessagemessage に設定する。

  3. this の内部スロットを次のように設定:

    [[Source]]

    options.source

    [[StreamErrorCode]]

    options.streamErrorCode

    注記: この name には従来コードへの対応付けがないため、 thiscode は 0 になる。

12.3. 属性

source, 型は WebTransportErrorSource、読み取り専用

取得子の手順は、this[[Source]] を返すことである。

streamErrorCode, 型は unsigned long、読み取り専用、null 許容

取得子の手順は、this[[StreamErrorCode]] を返すことである。

12.4. シリアライズ

WebTransportError オブジェクトはシリアライズ可能オブジェクトです。 そのシリアライズ手順valueserializedを与えて):

  1. DOMExceptionシリアライズ手順valueserializedで実行する。

  2. serialized.[[Source]]value.[[Source]]に設定。

  3. serialized.[[StreamErrorCode]]value.[[StreamErrorCode]]に設定。

そのデシリアライズ手順serializedvalueを与えて):

  1. DOMExceptionデシリアライズ手順serializedvalueで実行する。

  2. value.[[Source]]serialized.[[Source]]に設定。

  3. value.[[StreamErrorCode]] serialized.[[StreamErrorCode]]に設定。

13. プロトコルマッピング

この節は非規範的です。

この節では、[WEB-TRANSPORT-OVERVIEW] を用いて、本仕様で定義されるメソッドの基盤となるプロトコルの挙動を説明します。バッファリングにより、因果関係は即時でない場合があります。

WebTransportプロトコルアクション APIの効果
セッションが draining 状態になる await wt.draining

下層接続がHTTP/3の場合、[WEB-TRANSPORT-HTTP3]から以下のプロトコル挙動が適用されます。

WebTransportError エラーの application streamErrorCode は、httpErrorCode に変換され、またその逆も [WEB-TRANSPORT-HTTP3] Section 4.3 に従って行われます。

API メソッド QUIC プロトコル動作
writable.abort(error) STREAM の送信中断(httpErrorCode 指定、 かつ [[CommittedOffset]]stream 用)+ストリームヘッダ分のオフセット) 実施。 [RELIABLE-RESET] 参照
writable.close() STREAM を送信(FINビットセット)
writable.getWriter().write(chunk)() STREAM を送信
writable.getWriter().close() STREAM を送信(FINビットセット)
writable.getWriter().abort(error) STREAM の送信中断(httpErrorCode 指定、 かつ [[CommittedOffset]]stream 用)+ストリームヘッダ分のオフセット) 実施。 [RELIABLE-RESET] 参照
readable.cancel(error) STREAM の受信中断(httpErrorCode 指定)
readable.getReader().cancel(error) STREAM の受信中断(httpErrorCode 指定)
wt.close(closeInfo) セッション終了(closeInfo指定)
QUIC プロトコル動作 API の効果
httpErrorCode で STOP_SENDING 受信 エラー化 writablestreamErrorCode セット)
STREAM 受信 (await readable.getReader().read()).value
STREAM 受信 (FINビットセット) (await readable.getReader().read()).done
httpErrorCode で RESET_STREAM 受信 エラー化 readablestreamErrorCode セット)
セッションが cleanly 終了(closeInfo 指定)
(await wt.closed).closeInfo および エラー化 開いているストリーム
ネットワークエラー
(await wt.closed) が reject、および エラー化 開いているストリーム

注: [QUIC]の3.2節で述べられているように、 RESET_STREAMフレームやRESET_STREAM_ATフレーム([RELIABLE-RESET]) の受信は、必ずしもアプリケーションに通知されるわけではありません。 リセットの受信は即座にシグナルされ、 ストリームデータの配信が中断され、消費されていないデータは破棄されます。 ただし、即時のシグナルは必須ではありません。 特に、RESET_STREAM_ATフレームのReliable Sizeフィールドで指定されたデータの配信を許すため、 シグナルが遅延される場合があります。 ストリームデータが完全に受信されていて、 まだアプリケーションによって読み取られていない場合には、 送信中止シグナルが抑制されることがあります。 WebTransportは常にRESET_STREAM_ATフレームを使用し、 ストリームヘッダの確実な配信を保証します。 詳細は4.1節 および4.2節 [WEB-TRANSPORT-HTTP3]参照。

HTTP/3プロトコルアクション APIの効果
セッションが draining 状態になる await wt.draining

基盤接続がHTTP/2を使用している場合は、 [WEB-TRANSPORT-HTTP2]に記載されているプロトコル動作が適用されます。 HTTP/3の場合とは異なり、ストリームエラーコードをHTTPエラーコードに変換する必要はありませんし、逆も同様です。

API メソッド HTTP/2 プロトコル動作
writable.abort(error) WT_STREAM の送信中断(error 指定)
writable.close() WT_STREAM を送信(FIN ビットセット)
writable.getWriter().write() WT_STREAM を送信
writable.getWriter().close() WT_STREAM を送信(FIN ビットセット)
writable.getWriter().abort(error) WT_STREAM の送信中断(error 指定)
readable.cancel(error) WT_STREAM の受信中断(error 指定)
readable.getReader().cancel(error) WT_STREAM の受信中断(error 指定)
wt.close(closeInfo) セッション終了(closeInfo 指定)
HTTP/2 プロトコル動作 API の効果
error 付き WT_STOP_SENDING を受信 エラー化 writablestreamErrorCode セット)
WT_STREAM を受信 (await readable.getReader().read()).value
WT_STREAM を受信 (FINビットセット) (await readable.getReader().read()).done
error 付き WT_RESET_STREAM を受信 エラー化 readablestreamErrorCode セット)
セッションが cleanly 終了(closeInfo 指定)
(await wt.closed).closeInfo および エラー化 開いているストリーム
ネットワークエラー
(await wt.closed) が reject、および エラー化 開いているストリーム
セッションが draining 開始 await wt.draining

14. プライバシーおよびセキュリティに関する考慮事項

この節は非規範的であり、新しい挙動は規定せず、他の仕様部分に既に存在する情報をまとめたものです。

14.1. 通信の機密性

ネットワークを監視できる攻撃者に対して、通信が行われている事実を隠すことはできないため、これは公開情報として扱う必要があります。

本書で説明する全てのトランスポートプロトコルはTLS [RFC8446] またはそれと同等の意味を持つプロトコルを利用し、TLSの全てのセキュリティ特性(通信の機密性と完全性含む)を提供します。WebTransport over HTTPは、外向きHTTPリクエストと同じ証明書検証メカニズムを使用するため、リモートサーバーの認証に同じ公開鍵基盤に依存します。WebTransportでは、証明書検証エラーは致命的であり、証明書検証を回避するインタースティシャル(警告画面)はありません。

14.2. 状態の永続性

WebTransport自体は新しい一意な識別子や新たな永続的状態保存方法を作成せず、既存の永続的状態をサーバーに自動的に公開することもありません。例えば、[WEB-TRANSPORT-HTTP3][WEB-TRANSPORT-HTTP2] では、Cookieの送信やHTTP認証、キャッシュ無効化機構はサポートされません。ただしTLSを利用するため、TLSセッションチケットなどTLSの永続的状態を継承します。これは受動的ネットワーク監視者からは見えませんが、サーバー側が同じクライアントからの複数接続を関連付けるために利用できる場合があります。

14.3. プロトコルセキュリティ

WebTransportは[WEB-TRANSPORT-OVERVIEW]で記述された一連の要件を課します。主なものは以下の通りです:

  1. リモートサーバーが WebTransport プロトコルの使用を認識していることを保証し、リモートサーバーが WebTransport プロトコルの使用に同意していることを確認する。[WEB-TRANSPORT-HTTP3] では、ALPN と [RFC7301]、 HTTP/3 の設定、そして WebTransport プロトコルを識別するための :protocol 擬似ヘッダーの組み合わせを用いる。[WEB-TRANSPORT-HTTP2] では、ALPN、HTTP/2 の設定、 そして WebTransport プロトコルを識別するための :protocol 擬似ヘッダーの組み合わせを用いる。

  2. トランスポートセッションを開始するリソースのオリジンに基づいて、サーバーが接続をフィルタリングできるようにする。セッション確立要求の Origin ヘッダー フィールドがこの情報を伝達する。

プロトコルのセキュリティ関連事項については、 セキュリティに関する考慮事項の章で説明されています。 [WEB-TRANSPORT-OVERVIEW]セクション6[WEB-TRANSPORT-HTTP3]セクション8、 そして[WEB-TRANSPORT-HTTP2]セクション9を参照してください。

ネットワークAPIはローカルネットワークの利用可能なホストをスキャンする用途にも使われることが多く、フィンガープリントやその他攻撃手法に利用される可能性があります。WebTransportはWebSocketのアプローチに従います:特定の接続エラーは、エンドポイントがWebTransportエンドポイントであることが検証されるまで返されません。つまりWebアプリケーションは、存在しないエンドポイントとWebからの接続受け入れ意思のないエンドポイントとを区別できません。

14.4. 証明書ハッシュを使用するサーバー認証

通常、ユーザーエージェントは、URLのサーバー名に対して提供されたTLSサーバー証明書の有効性を検証することで、TLS接続の認証を行います [RFC9525]。これは、ユーザーエージェントが管理する信頼できるアンカーに証明書チェーンをつなげることで達成されます。信頼アンカーは証明書内のサーバー名認証を担当します。この仕組みをWeb PKIと呼びます。

このAPIは、Webアプリケーションが、サーバー名ではなく特定のサーバー証明書で認証されたリモートネットワークエンドポイントに接続する機能を提供します。この仕組みは、長期証明書の取得が困難なエンドポイント(例:短命な仮想マシンや公開ルート不可なホスト)への接続を可能にします。この仕組みはWeb PKIベース認証の代替となるため、両者のセキュリティ特性を比較する必要があります。

リモートサーバーは、指定された証明書の公開鍵に対応する秘密鍵を保持している場合のみ、TLSハンドシェイクに成功できます。APIは証明書のハッシュで証明書を識別します。これは使用する暗号学的ハッシュ関数がセカンドプリイメージ耐性を持つ場合のみ安全です。本書で定義される唯一の関数はSHA-256であり、APIは複数のアルゴリズム-ハッシュペア指定により新たなハッシュ関数の導入手段を提供します。

Web PKIはサーバー名の信頼チェーン構築以外にも、証明書失効処理など追加のセキュリティ機構を提供します。証明書がエフェメラルな場合はこの機構は不要ですが、その他の場合は証明書ハッシュの導入方法(例:キャッシュされたHTTPリソースの場合、証明書が侵害により交換された際はキャッシュを無効化する必要がある)を検討する必要があります。Web PKIは、既知の弱い鍵を持つ証明書の拒否など、鍵生成に関する問題への対策も提供します。本仕様では特定の指針はありませんが、ブラウザは実装依存でこれらを拒否しても構いません。

Web PKIは証明書の有効期間制限を課します。これは鍵侵害の範囲を限定し、運用者が鍵ローテーションを設計・実行する仕組みとなります。WebTransportも同様の有効期間制限(最大2週間)を課します。2週間という制限は、鍵侵害の影響最小化と、デバイス間の時計ズレやクライアントとサーバー間での証明書同期コスト低減のバランスを考慮したものです。

WebTransport APIは、アプリケーションが複数の証明書ハッシュを同時に指定できるようにし、新しい証明書がロールアウトされる期間中クライアントが複数の証明書を受け入れられるようにします。

WebRTCの類似の仕組みと異なり、WebTransportのサーバー証明書ハッシュAPIはクライアント認証手段を提供しません。クライアントがサーバー証明書や接続方法を知っているだけでは十分ではなく、必要に応じてアプリケーションがバンド内でクライアントのアイデンティティを確立する必要があります。

14.5. フィンガープリントとトラッキング

このAPIはサイトにネットワーク活動を生成し、その効果を詳細に観察する能力を提供します。このように得られた情報は識別可能である可能性があります。

非常によく似たネットワーク機能が、他の Web プラットフォーム API( fetch()WebSocket など)によって提供されていることを認識することが重要である。 したがって、WebTransport を追加することによるプライバシーへの 正味の悪影響は最小限である。この節の考慮事項は、他のネットワーク機能にも同様に適用される。

ネットワーク特性の計測にはネットワーク利用とその利用効果の計測が必要であり、どちらもこのAPIによって可能となります。WebTransportはサイトに、任意のサーバーへのネットワーク活動生成および効果の観察能力を提供します。ネットワーク経路の安定した特性や動的な利用効果の両方の観察が可能です。

ネットワーク情報は、サーバー自身のネットワークスタック、クライアントによるデータ消費・送信速度、またはAPIが提供する統計情報(§ 6.13 WebTransportConnectionStats Dictionary参照)としてサーバーに直接・間接的に提供されます。そのため、ユーザーエージェントで情報制限するだけではプライバシーリスク管理には不十分な場合があります。

14.5.1. 静的観測

サイトはユーザーエージェントと選択したサーバー間の利用可能なネットワーク容量やRTT(往復遅延時間)を観測できます。これらの情報は他のトラッキング要素と組み合わせると識別性を持つ場合があります。RTTは複数地点から複数回測定することでユーザーエージェントの物理的な位置情報の一部を明らかにできる場合もあります。

ネットワークは共有されているものの、利用は断続的なことが多いため、サイトは競合や負荷の少ない経路の容量やRTTを観測できる場合があります。これらの特性は多くの人にとって安定しており、ネットワークの位置が変わらず、ボトルネック(容量決定要素)がユーザーエージェントに近い場合は特に安定します。

14.5.2. 共有ネットワーク

競合するリンクでは、サイトにクロスサイト認識 の機会が生まれ、これが非公認のトラッキング([UNSANCTIONED-TRACKING])に利用される恐れがあります。 ネットワーク容量は有限で共有資源のため、ユーザーエージェントが複数サイトに同時アクセスする場合、各サイトに提示されるアイデンティティの関連付けが明らかになる場合があります。

一つのサイトでネットワーク機能を使うと、他サイトで利用できる容量が減少し、ネットワークAPIを使って観測できます。ネットワーク利用やメトリクスは動的に変化し、変化はリアルタイムで観測可能です。これにより、異なるサイト上の活動が同一ユーザーによるものであるという確信度を高めることができます。

ユーザーエージェントは、アクティブでない・フォーカスされていないサイトに対して、フィードバック機構(統計情報、§ 6.13 WebTransportConnectionStats Dictionary)へのアクセスを制限・劣化させることができます。ただし、これだけではサーバーがネットワークの変化を観測することを防ぎきれません。

14.5.3. セッションのプール

共有ネットワークのシナリオと同様、セッションが単一の接続上でプールされる場合、あるセッションの情報は他のセッションの活動によって影響を受けます。別のセッションがどの程度データを送信しているかなどの情報が推論される可能性があります。

共有接続の利用は、サーバー側がセッションを関連付けることを可能にします。network partition keyを使用すると、プール利用が無効化され、共有セッションが不要なクロスサイト認識を可能にする状況を防ぐことができます。

15.

15.1. データグラムバッファの送信

この節は非規範的です。

データグラムのバッファ送信は、datagramscreateWritable メソッドおよびその結果のストリームのwriterを利用して実現できます。下記例では、トランスポートが送信可能な場合のみデータグラムを送信します。

async function sendDatagrams(url, datagrams) {
  const wt = new WebTransport(url);
  const writable = wt.datagrams.createWritable();
  const writer = writable.getWriter();
  for (const bytes of datagrams) {
    await writer.ready;
    writer.write(bytes).catch(() => {});
  }
  await writer.close();
}

15.2. 一定レートでデータグラム送信

この節は非規範的です。

トランスポートが送信可能かどうかに関わらず一定レートでデータグラムを送信したい場合は、datagramscreateWritable メソッドと、その結果のストリームのwriterをready属性を待たずに使えばよいです。

// 100msごとにデータグラム送信
async function sendFixedRate(url, createDatagram, ms = 100) {
  const wt = new WebTransport(url);
  const writable = wt.datagrams.createWritable();
  const writer = writable.getWriter();
  const bytes = createDatagram();
  setInterval(() => writer.write(bytes).catch(() => {}), ms);
}

15.3. データグラム受信

この節は非規範的です。

データグラムはtransport.datagrams.readable 属性から読み出すことで受信できます。null値はパケット処理が遅すぎることを示す場合があります。

async function receiveDatagrams(url) {
  const wt = new WebTransport(url);
  for await (const datagram of wt.datagrams.readable) {
    // datagramを処理
  }
}

15.4. BYOBリーダーによるデータグラム受信

この節は非規範的です。

datagrams可読バイトストリームであるため、バッファ割当てをより正確に制御しコピーを避けるための BYOBリーダー を取得できる。この例では64キビバイトのメモリバッファにデータグラムを読み出している。

const wt = new WebTransport(url);

for await (const datagram of wt.datagrams.readable) {
  const reader = datagram.getReader({ mode: "byob" });

  let array_buffer = new ArrayBuffer(65536);
  const buffer = await readInto(array_buffer);
}

async function readInto(buffer) {
  let offset = 0;

  while (offset < buffer.byteLength) {
    const {value: view, done} = await reader.read(
        new Uint8Array(buffer, offset, buffer.byteLength - offset));
    buffer = view.buffer;
    if (done) {
      break;
    }
    offset += view.byteLength;
  }

  return buffer;
}

15.5. ストリーム送信

この節は非規範的です。

一方向ストリームでデータを送信するには、createUnidirectionalStream 関数およびその結果のストリームのwriterを利用します。

書き込みchunkの境界は受信側で保証されません。バイトがワイヤ上で合流する可能性があるため、アプリケーションは独自フレーミングを推奨します。

async function sendData(url, ...data) {
  const wt = new WebTransport(url);
  const writable = await wt.createUnidirectionalStream();
  const writer = writable.getWriter();
  for (const bytes of data) {
    await writer.ready;
    writer.write(bytes).catch(() => {});
  }
  await writer.close();
}

Streams仕様では write()のawait を推奨しません。

エンコーディングは、ReadableStreamからpipeすることで実現できます。 例えばTextEncoderStream を用います。

async function sendText(url, readableStreamOfTextData) {
  const wt = new WebTransport(url);
  const writable = await wt.createUnidirectionalStream();
  await readableStreamOfTextData
    .pipeThrough(new TextEncoderStream("utf-8"))
    .pipeTo(writable);
}

15.6. 着信ストリームの受信

この節は非規範的です。

着信ストリームの読み出しは、incomingUnidirectionalStreams 属性を反復し、各WebTransportReceiveStream のチャンクを反復処理することで実現できます。

チャンク化はユーザーエージェントによって決定され、送信者ではありません。

async function receiveData(url, processTheData) {
  const wt = new WebTransport(url);
  for await (const readable of wt.incomingUnidirectionalStreams) {
    // 各ストリームを個別に消費し、ストリームごとのエラーを報告
    ((async () => {
      try {
        for await (const bytes of readable) {
          processTheData(bytes);
        }
      } catch (e) {
        console.error(e);
      }
    })());
  }
}

デコードは新しいWritableStreamにpipeすることで実現できます。例えば TextDecoderStream を使います。 この例ではテキスト出力が混在しないよう、1ストリームずつ読み取ります。

async function receiveText(url, createWritableStreamForTextData) {
  const wt = new WebTransport(url);
  for await (const readable of wt.incomingUnidirectionalStreams) {
    // 順次消費して出力を混在させず、ストリームごとのエラーを報告
    try {
      await readable
       .pipeThrough(new TextDecoderStream("utf-8"))
       .pipeTo(createWritableStreamForTextData());
    } catch (e) {
      console.error(e);
    }
  }
}

15.7. BYOBリーダーでストリーム受信

この節は非規範的です。

WebTransportReceiveStream読み取りバイトストリームなので、コピーを避けるために より精密なバッファ割り当て制御ができるBYOBリーダーを取得できます。 この例では、WebTransportReceiveStream から最初の1024バイトを単一のメモリバッファに読み取ります。

const wt = new WebTransport(url);

const reader = wt.incomingUnidirectionalStreams.getReader();
const { value: recv_stream, done } = await reader.read();
const byob_reader = recv_stream.getReader({ mode: "byob" });

let array_buffer = new ArrayBuffer(1024);
const buffer = await readInto(array_buffer);

async function readInto(buffer) {
  let offset = 0;

  while (offset < buffer.byteLength) {
    const {value: view, done} = await reader.read(
        new Uint8Array(buffer, offset, buffer.byteLength - offset));
    buffer = view.buffer;
    if (done) {
      break;
    }
    offset += view.byteLength;
  }

  return buffer;
}

15.8. ストリームでトランザクションチャンク送信

このセクションは参考(規定ではありません)。

トランザクション性のあるデータを単方向ストリームで送信する際、フロー制御によるブロックなしに全体を一度に送信できる場合のみ送信するには、 getWriter 関数およびその戻り値の writer を利用することで実現できます。

async function sendTransactionalData(wt, bytes) {
  const writable = await wt.createUnidirectionalStream();
  const writer = writable.getWriter();
  await writer.ready;
  try {
    await writer.atomicWrite(bytes);
  } catch (e) {
    if (e.name != "AbortError") throw e;
    // フロー制御でブロックを避けるためreject
    // 非atomicな書き込みがpendingでなければwritableはエラー化されない
  } finally {
    writer.releaseLock();
  }
}

15.9. サーバー証明書ハッシュ利用

この節は非規範的です。

WebTransportセッションは、クライアント側で行われるデフォルトの信頼評価を、サーバーに提供された証明書のハッシュによるチェックで上書きできます。下記例ではhashValue下層接続が有効とみなすべきサーバー証明書のSHA-256ハッシュを含むBufferSourceです。

const wt = new WebTransport(url, {
  serverCertificateHashes: [
    {
      algorithm: "sha-256",
      value: hashValue,
    }
  ]
});
await wt.ready;

15.10. 完全な例

この節は非規範的です。

この例はclosed/ready promiseの利用、クライアント・サーバー双方での一方向・双方向ストリームの開始、データグラムの送受信方法を示します。

writable属性(transportのdatagramsにあったもの)は 以下のようにPolyfillできます:
wt.datagrams.writable ||= wt.datagrams.createWritable();
// ページ上のイベントログにエントリを追加し、指定CSSクラスを適用可能
// CSSクラスを任意指定

let wt, streamNumber, datagramWriter;

connect.onclick = async () => {
  try {
    const url = document.getElementById('url').value;

    wt = new WebTransport(url);
    wt.datagrams.writable ||= wt.datagrams.createWritable();
    addToEventLog('接続を開始しています...');
    await wt.ready;
    addToEventLog(`${(wt.reliability == "reliable-only")? "TCP" : "UDP"} ` +
                  `接続完了.`);
    wt.closed
      .then(() => addToEventLog('接続が正常に閉じられました。'))
      .catch(() => addToEventLog('接続が異常終了しました。', 'error'));

    streamNumber = 1;
    datagramWriter = wt.datagrams.writable.getWriter();

    readDatagrams();
    acceptUnidirectionalStreams();
    document.forms.sending.elements.send.disabled = false;
    document.getElementById('connect').disabled = true;
  } catch (e) {
    addToEventLog(`接続失敗: ${e}`, 'error');
  }
}

sendData.onclick = async () => {
  const form = document.forms.sending.elements;
  const data = sending.data.value;
  const bytes = new TextEncoder('utf-8').encode(data);
  try {
    switch (form.sendtype.value) {
      case 'datagram': {
        await datagramWriter.ready;
        datagramWriter.write(bytes).catch(() => {});
        addToEventLog(`データグラム送信: ${data}`);
        break;
      }
      case 'unidi': {
        const writable = await wt.createUnidirectionalStream();
        const writer = writable.getWriter();
        writer.write(bytes).catch(() => {});
        await writer.close();
        addToEventLog(`一方向ストリームでデータ送信: ${data}`);
        break;
      }
      case 'bidi': {
        const duplexStream = await wt.createBidirectionalStream();
        const n = streamNumber++;
        readFromIncomingStream(duplexStream.readable, n);

        const writer = duplexStream.writable.getWriter();
        writer.write(bytes).catch(() => {});
        await writer.close();
        addToEventLog(`双方向ストリーム #${n} でデータ送信: ${data}`);
        break;
      }
    }
  } catch (e) {
    addToEventLog(`送信中のエラー: ${e}`, 'error');
  }
}

// EOF到達までデータグラムをイベントログに読み出し
async function readDatagrams() {
  try {
    const decoder = new TextDecoderStream('utf-8');

    for await (const data of wt.datagrams.readable.pipeThrough(decoder)) {
      addToEventLog(`データグラム受信: ${data}`);
    }
    addToEventLog('データグラム読み取り終了!');
  } catch (e) {
    addToEventLog(`データグラム読取中のエラー: ${e}`, 'error');
  }
}

async function acceptUnidirectionalStreams() {
  try {
    for await (const readable of wt.incomingUnidirectionalStreams) {
      const number = streamNumber++;
      addToEventLog(`新しい着信一方向ストリーム #${number}`);
      readFromIncomingStream(readable, number);
    }
    addToEventLog('着信一方向ストリーム受付終了!');
  } catch (e) {
    addToEventLog(`ストリーム受付中エラー ${e}`, 'error');
  }
}

async function readFromIncomingStream(readable, number) {
  try {
    const decoder = new TextDecoderStream('utf-8');
    for await (const data of readable.pipeThrough(decoder)) {
      addToEventLog(`ストリーム #${number} でデータ受信: ${data}`);
    }
    addToEventLog(`ストリーム #${number} 閉じました`);
  } catch (e) {
    addToEventLog(`ストリーム #${number} 読取中のエラー: ${e}`, 'error');
    addToEventLog(`    ${e.message}`);
  }
}

function addToEventLog(text, severity = 'info') {
  const log = document.getElementById('event-log');
  const previous = log.lastElementChild;
  const entry = document.createElement('li');
  entry.innerText = text;
  entry.className = `log-${severity}`;
  log.appendChild(entry);

  // ログの直前のエントリが可視なら、新しい要素までスクロール
  if (previous &&
      previous.getBoundingClientRect().top < log.getBoundingClientRect().bottom) {
    entry.scrollIntoView();
  }
}

16. 謝辞

編集者は、ワーキンググループ議長およびチームコンタクトである Jan-Ivar Bruaroey、Will Law、Yves Lafon のご支援に感謝します。

WebTransport インターフェイスは、W3C ORTC CGで最初に記述された QuicTransport インターフェイスに基づいており、本仕様に合わせて適合・拡張されています。

索引

本仕様で定義される用語

参照によって定義される用語

参考文献

規範的参考文献

[CSP3]
Mike West; Antonio Sartori. コンテンツセキュリティポリシー レベル 3. 2026年5月5日. WD. URL: https://www.w3.org/TR/CSP3/
[CSS2]
Bert Bos; ほか. カスケーディングスタイルシート レベル 2 リビジョン 1(CSS 2.1)仕様. 2011年6月7日. REC. URL: https://www.w3.org/TR/CSS2/
[DOM]
Anne van Kesteren. DOM 標準. Living Standard. URL: https://dom.spec.whatwg.org/
[ECMASCRIPT-6.0]
Allen Wirfs-Brock. ECMA-262 第6版、 ECMAScript 2015 言語仕様. 2015年6月. 標準. URL: http://www.ecma-international.org/ecma-262/6.0/index.html
[ENCODING]
Anne van Kesteren. Encoding 標準. Living Standard. URL: https://encoding.spec.whatwg.org/
[FETCH]
Anne van Kesteren. Fetch 標準. Living Standard. URL: https://fetch.spec.whatwg.org/
[HR-TIME-3]
Yoav Weiss. 高解像度時刻. 2026年3月24日. WD. URL: https://www.w3.org/TR/hr-time-3/
[HTML]
Anne van Kesteren; ほか. HTML 標準. Living Standard. URL: https://html.spec.whatwg.org/multipage/
[INFRA]
Anne van Kesteren; Domenic Denicola. Infra 標準. Living Standard. URL: https://infra.spec.whatwg.org/
[QUIC]
Jana Iyengar; Martin Thomson. QUIC:UDPベースの 多重化された安全なトランスポート. 提案標準. URL: https://www.rfc-editor.org/rfc/rfc9000
[QUIC-DATAGRAM]
Tommy Pauly; Eric Kinnear; David Schinazi. QUIC の 信頼性のないデータグラム拡張. 提案標準. URL: https://www.rfc-editor.org/rfc/rfc9221
[RFC2119]
S. Bradner. 要求レベルを示すために RFC で 使用されるキーワード. 1997年3月. 最良現行慣行. URL: https://datatracker.ietf.org/doc/html/rfc2119
[RFC3279]
L. Bassham; W. Polk; R. Housley. インターネット X.509 公開鍵基盤の証明書および証明書失効リスト(CRL)プロファイルのためのアルゴリズムと識別子. 2002年5月. 提案標準. URL: https://www.rfc-editor.org/info/rfc3279/
[RFC5280]
D. Cooper; ほか. インターネット X.509 公開鍵 基盤の証明書および証明書失効リスト(CRL)プロファイル. 2008年5月. 提案標準. URL: https://www.rfc-editor.org/info/rfc5280/
[RFC8174]
B. Leiba. RFC 2119 キーワードにおける 大文字と小文字の曖昧性. 2017年5月. 最良現行慣行. URL: https://www.rfc-editor.org/info/rfc8174/
[RFC8422]
Y. Nir; S. Josefsson; M. Pegourie-Gonnard. TLS バージョン 1.2 以前のための楕円曲線暗号(ECC)暗号スイート. 2018年8月. 提案標準. URL: https://www.rfc-editor.org/info/rfc8422/
[RFC8441]
P. McManus. HTTP/2 による WebSocket の ブートストラップ. 2018年9月. 提案標準. URL: https://httpwg.org/specs/rfc8441.html
[RFC9002]
J. Iyengar, Ed.; I. Swett, Ed.. QUIC 損失検出 および輻輳制御. 2021年5月. 提案標準. URL: https://www.rfc-editor.org/info/rfc9002/
[RFC9220]
R. Hamilton. HTTP/3 による WebSocket の ブートストラップ. 2022年6月. 提案標準. URL: https://httpwg.org/specs/rfc9220.html
[RFC9525]
P. Saint-Andre; R. Salz. TLS におけるサービス アイデンティティ. 2023年11月. 提案標準. URL: https://www.rfc-editor.org/info/rfc9525/
[STREAMS]
Adam Rice; ほか. Streams 標準. Living Standard. URL: https://streams.spec.whatwg.org/
[URL]
Anne van Kesteren. URL 標準. Living Standard. URL: https://url.spec.whatwg.org/
[WEB-TRANSPORT-HTTP2]
Alan Frindell; ほか. HTTP/2 上の WebTransport. Internet-Draft. URL: https://datatracker.ietf.org/doc/html/draft-ietf-webtrans-http2
[WEB-TRANSPORT-HTTP3]
Alan Frindell; Eric Kinnear; Victor Vasiliev. HTTP/3 上の WebTransport. Internet-Draft. URL: https://datatracker.ietf.org/doc/html/draft-ietf-webtrans-http3
[WEB-TRANSPORT-OVERVIEW]
Victor Vasiliev. WebTransport プロトコル フレームワーク. Internet-Draft. URL: https://datatracker.ietf.org/doc/html/draft-ietf-webtrans-overview
[WEBIDL]
Edgar Chen; Timothy Gu. Web IDL 標準. Living Standard. URL: https://webidl.spec.whatwg.org/
[WEBSOCKETS]
Adam Rice. WebSockets 標準. Living Standard. URL: https://websockets.spec.whatwg.org/

参考情報

[RELIABLE-RESET]
Marten Seemann; 奥一穂. 部分配信を伴う QUIC ストリーム リセット. Internet-Draft. URL: https://datatracker.ietf.org/doc/html/draft-ietf-quic-reliable-stream-reset
[RFC7301]
S. Friedl; ほか. Transport Layer Security(TLS) アプリケーション層プロトコルネゴシエーション拡張. 2014年7月. 提案標準. URL: https://www.rfc-editor.org/info/rfc7301/
[RFC8446]
E. Rescorla. Transport Layer Security(TLS) プロトコル バージョン 1.3. 2018年8月. 提案標準. URL: https://www.rfc-editor.org/info/rfc8446/
[RFC9308]
M. Kühlewind; B. Trammell. QUIC トランスポート プロトコルの適用可能性. 2022年9月. 情報提供. URL: https://www.rfc-editor.org/info/rfc9308/
[UNSANCTIONED-TRACKING]
Mark Nottingham. 認可されていない Web トラッキング. 2015年7月17日. TAG 所見. URL: https://www.w3.org/2001/tag/doc/unsanctioned-tracking/

IDL索引

[Exposed=(Window,Worker), SecureContext, Transferable]
interface WebTransportDatagramsWritable : WritableStream {
  attribute WebTransportSendGroup? sendGroup;
  attribute long long sendOrder;
};

[Exposed=(Window,Worker), SecureContext]
interface WebTransportDatagramDuplexStream {
  WebTransportDatagramsWritable createWritable(
      optional WebTransportSendOptions options = {});
  readonly attribute ReadableStream readable;

  readonly attribute unsigned long maxDatagramSize;
  attribute unrestricted double? incomingMaxAge;
  attribute unrestricted double? outgoingMaxAge;
  attribute unsigned long incomingMaxBufferedDatagrams;
  attribute unsigned long outgoingMaxBufferedDatagrams;
};

[Exposed=(Window,Worker), SecureContext]
interface WebTransport {
  constructor(USVString url, optional WebTransportOptions options = {});

  Promise<WebTransportConnectionStats> getStats();
  [NewObject] Promise<Uint8Array> exportKeyingMaterial(BufferSource label, BufferSource context, unsigned long outputLength);
  readonly attribute Promise<undefined> ready;
  readonly attribute WebTransportReliabilityMode reliability;
  readonly attribute WebTransportCongestionControl congestionControl;
  attribute [EnforceRange] unsigned short? anticipatedConcurrentIncomingUnidirectionalStreams;
  attribute [EnforceRange] unsigned short? anticipatedConcurrentIncomingBidirectionalStreams;
  [SameObject] readonly attribute Headers? responseHeaders;
  readonly attribute DOMString protocol;

  readonly attribute Promise<WebTransportCloseInfo> closed;
  readonly attribute Promise<undefined> draining;
  undefined close(optional WebTransportCloseInfo closeInfo = {});

  readonly attribute WebTransportDatagramDuplexStream datagrams;

  Promise<WebTransportBidirectionalStream> createBidirectionalStream(
      optional WebTransportSendStreamOptions options = {});
  /* a ReadableStream of WebTransportBidirectionalStream objects */
  readonly attribute ReadableStream incomingBidirectionalStreams;

  Promise<WebTransportSendStream> createUnidirectionalStream(
      optional WebTransportSendStreamOptions options = {});
  /* a ReadableStream of WebTransportReceiveStream objects */
  readonly attribute ReadableStream incomingUnidirectionalStreams;
  WebTransportSendGroup createSendGroup();

  static readonly attribute boolean supportsReliableOnly;
};

enum WebTransportReliabilityMode {
  "pending",
  "reliable-only",
  "supports-unreliable",
};

dictionary WebTransportHash {
  required DOMString algorithm;
  required BufferSource value;
};

dictionary WebTransportOptions {
  boolean allowPooling = false;
  boolean requireUnreliable = false;
  HeadersInit headers = {};
  sequence<WebTransportHash> serverCertificateHashes = [];
  WebTransportCongestionControl congestionControl = "default";
  [EnforceRange] unsigned short? anticipatedConcurrentIncomingUnidirectionalStreams = null;
  [EnforceRange] unsigned short? anticipatedConcurrentIncomingBidirectionalStreams = null;
  sequence<DOMString> protocols = [];
  ReadableStreamType datagramsReadableType;
};

enum WebTransportCongestionControl {
  "default",
  "throughput",
  "low-latency",
};

dictionary WebTransportCloseInfo {
  unsigned long closeCode = 0;
  USVString reason = "";
};

dictionary WebTransportSendOptions {
  WebTransportSendGroup? sendGroup = null;
  long long sendOrder = 0;
};

dictionary WebTransportSendStreamOptions : WebTransportSendOptions {
  boolean waitUntilAvailable = false;
};

dictionary WebTransportConnectionStats {
  unsigned long long bytesSent;
  unsigned long long bytesSentOverhead;
  unsigned long long bytesAcknowledged;
  unsigned long long packetsSent;
  unsigned long long bytesLost;
  unsigned long long packetsLost;
  unsigned long long bytesReceived;
  unsigned long long packetsReceived;
  DOMHighResTimeStamp smoothedRtt;
  DOMHighResTimeStamp rttVariation;
  DOMHighResTimeStamp minRtt;
  required WebTransportDatagramStats datagrams;
  unsigned long long? estimatedSendRate = null;
  boolean atSendCapacity = false;
};

dictionary WebTransportDatagramStats {
  unsigned long long droppedIncoming;
  unsigned long long expiredIncoming;
  unsigned long long expiredOutgoing;
  unsigned long long lostOutgoing;
};

[Exposed=(Window,Worker), SecureContext, Transferable]
interface WebTransportSendStream : WritableStream {
  attribute WebTransportSendGroup? sendGroup;
  attribute long long sendOrder;
  Promise<WebTransportSendStreamStats> getStats();
  WebTransportWriter getWriter();
};

dictionary WebTransportSendStreamStats {
  unsigned long long bytesWritten;
  unsigned long long bytesSent;
  unsigned long long bytesAcknowledged;
};

[Exposed=(Window,Worker), SecureContext]
interface WebTransportSendGroup {
  Promise<WebTransportSendStreamStats> getStats();
};

[Exposed=(Window,Worker), SecureContext, Transferable]
interface WebTransportReceiveStream : ReadableStream {
  Promise<WebTransportReceiveStreamStats> getStats();
};

dictionary WebTransportReceiveStreamStats {
  unsigned long long bytesReceived;
  unsigned long long bytesRead;
};

[Exposed=(Window,Worker), SecureContext]
interface WebTransportBidirectionalStream {
  readonly attribute WebTransportReceiveStream readable;
  readonly attribute WebTransportSendStream writable;
};

[Exposed=*, SecureContext]
interface WebTransportWriter : WritableStreamDefaultWriter {
  Promise<undefined> atomicWrite(optional any chunk);
  undefined commit();
};

[Exposed=(Window,Worker), Serializable, SecureContext]
interface WebTransportError : DOMException {
  constructor(optional DOMString message = "", optional WebTransportErrorOptions options = {});

  readonly attribute WebTransportErrorSource source;
  readonly attribute unsigned long? streamErrorCode;
};

dictionary WebTransportErrorOptions {
  WebTransportErrorSource source = "stream";
  [Clamp] unsigned long? streamErrorCode = null;
};

enum WebTransportErrorSource {
  "stream",
  "session",
};

課題索引

これはWorkerでも対応する必要があります。詳細は #127 および whatwg/html#6731 を参照してください。

この設定オプションは、現時点で低遅延最適化の輻輳制御アルゴリズムをブラウザが実装していないため、リスクのある機能と見なされています。

bytesAcknowledgedWebTransportConnectionStats において、実装可能性に関する懸念からワーキンググループによりリスクあり機能(feature at risk)と識別されている。