1. 소개
이 섹션은 규범적인 내용이 아닙니다.
이 명세는 [WEB-TRANSPORT-OVERVIEW]를 사용하여 서버로 데이터를 보내고 받을 수 있습니다. 이는 WebSocket과 유사하게 사용할 수 있지만, 다중 스트림, 단방향 스트림, 순서가 뒤바뀐 전달, 그리고 신뢰성 있는 전송과 비신뢰성 전송을 모두 지원합니다.
참고: 이 명세에서 제공하는 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에는 두 가지 주요 프로토콜 개념이 있습니다: 세션과 스트림. 각 WebTransport 세션은 여러 개의 WebTransport 스트림을 포함할 수 있습니다.
이들은 프로토콜 이름과 혼동해서는 안 되며, 이는 애플리케이션 수준의 API 구조입니다.
3.1. WebTransport 세션
WebTransport 세션은 HTTP/3 또는 HTTP/2 하위 연결에서의 WebTransport 세션입니다. 풀링이 활성화되면 하나의 연결에 여러 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은 드레이닝(draining) 상태이며, CONNECT 스트림이 서버에 의해 정상적으로 닫히도록 요청받았을 때, [WEB-TRANSPORT-OVERVIEW] 섹션 4.1에 설명되어 있습니다.
WebTransport 세션 session을 선택적 정수 code와 선택적 바이트 시퀀스 reason과 함께 종료하기(terminate) 위해서는, [WEB-TRANSPORT-OVERVIEW] 섹션 4.1을 따릅니다.
WebTransport 세션 session이 종료되었다(terminated)고 하며, 선택적으로 정수 code와 바이트 시퀀스 reason을 포함할 수 있고, CONNECT 스트림이 서버에 의해 닫혔을 때, [WEB-TRANSPORT-OVERVIEW] 섹션 4.1에 설명되어 있습니다.
3.2. WebTransport 스트림
WebTransport 스트림은 WebTransport 세션 상에서의 신뢰성 있는 순차적 바이트 스트림 개념이며, [WEB-TRANSPORT-OVERVIEW] 섹션 4.3에 설명되어 있습니다.
WebTransport 스트림은 도착 단방향, 출발 단방향 또는 양방향 중 하나입니다.
이는 원자적 쓰기를
포함합니다.
원자적 쓰기는 흐름 제어 교착 상태를 방지하기 위해 존재하며,
데이터가 함께 전달될 것이라는 보장은 제공하지 않습니다.
송신자와 수신자 간의 메시지 경계를 보존해야 하는 메시지 기반 프로토콜에 의존하는 애플리케이션은 메시지를 재구성할 수 있도록 구분 레이어를 추가해야 합니다.
WebTransport 스트림은 다음과 같은 기능을 가집니다:
| 기능 | 정의 | 수신 단방향 | 송신 단방향 | 양방향 |
|---|---|---|---|---|
| 바이트 전송 (FIN 가능) | [WEB-TRANSPORT-OVERVIEW] 섹션 4.3 | 아니오 | 예 | 예 |
| 바이트 수신 (FIN 가능) | [WEB-TRANSPORT-OVERVIEW] 섹션 4.3 | 예 | 아니오 | 예 |
| 수신 중단 WebTransport 스트림에서 | [WEB-TRANSPORT-OVERVIEW] 섹션 4.3 | 예 | 아니오 | 예 |
| 송신 중단 WebTransport 스트림에서 | [WEB-TRANSPORT-OVERVIEW] 섹션 4.3 | 아니오 | 예 | 예 |
WebTransport 스트림은 다음과 같은 신호를 가집니다:
| 이벤트 | 정의 | 수신 단방향 | 송신 단방향 | 양방향 |
|---|---|---|---|---|
| 수신 중단됨 | [WEB-TRANSPORT-OVERVIEW] 섹션 4.3 | 아니오 | 예 | 예 |
| 송신 중단됨 | [WEB-TRANSPORT-OVERVIEW] 섹션 4.3 | 예 | 아니오 | 예 |
| 흐름 제어 | [WEB-TRANSPORT-OVERVIEW] 섹션 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]]
| 내보내는 데이터그램, 타임스탬프 및 데이터그램이 전송되거나 폐기될 때 resolve되는 promise의 튜플 큐 |
[[Transport]]
| 이 WebTransport를
소유하는 WebTransportDatagramsWritable
|
[[SendGroup]]
| 옵션의 WebTransportSendGroup
또는 null
|
[[SendOrder]]
| 옵션 전송 순서 번호, 기본값 0 |
WebTransportDatagramsWritable
을 주어진 WebTransport
transport와 sendGroup,
그리고 sendOrder와 함께 다음 단계를 수행
-
stream을 new
WebTransportDatagramsWritable로, 아래와 같이 생성:[[OutgoingDatagramsQueue]]-
빈 큐
[[Transport]]-
transport
[[SendGroup]]-
sendGroup
[[SendOrder]]-
sendOrder
-
writeDatagramsAlgorithm을 writeDatagrams를 transport와 stream으로 실행하는 액션으로 설정
-
Set up stream의 writeAlgorithm을 writeDatagramsAlgorithm으로 설정
-
stream을 반환
4.2. 속성
sendGroup, 타입 WebTransportSendGroup, nullable-
getter 단계:
-
this의
[[SendGroup]]을 반환합니다.
setter 단계 (값 value 주어짐):
-
value가 null이 아니고, value.
[[Transport]]이 this.[[Transport]]와 다르면, InvalidStateError 예외를 throw합니다. -
this.
[[SendGroup]]을 value로 설정합니다.
-
sendOrder, 타입 long long-
getter 단계:
-
this의
[[SendOrder]]을 반환합니다.
setter 단계 (값 value 주어짐):
-
this.
[[SendOrder]]을 value로 설정합니다.
-
4.3. 절차
writeDatagrams 알고리즘은 transport와 writable을 매개변수로 하고, 입력으로 data를 받습니다. 다음 단계로 정의합니다:
-
timestamp를 현재 시점을 나타내는 타임스탬프로 설정합니다.
-
만약 data가
BufferSource객체가 아니라면, 거부된 promise와 함께TypeError를 반환한다. -
datagrams를 transport.
[[Datagrams]]로 설정합니다. -
datagrams.
[[OutgoingMaxDatagramSize]]가 data의 [[ByteLength]]보다 작으면, undefined로 해결된 프로미스를 반환합니다. -
새 프로미스 promise를 생성합니다.
-
data가 나타내는 바이트를 복사하여 bytes로 설정합니다.
-
chunk를 bytes, timestamp, promise의 튜플로 설정합니다.
-
writable.
[[OutgoingDatagramsQueue]]에 chunk를 큐에 추가합니다. -
writable.
[[OutgoingDatagramsQueue]]의 길이가 datagrams.[[OutgoingMaxBufferedDatagrams]]보다 작으면, promise를 undefined로 resolve합니다. -
promise를 반환합니다.
참고: 관련 WritableStream은
해당 스트림에 대해 writeDatagrams로 반환된 모든 프로미스가 resolve된 후에만 writeDatagrams를 호출합니다. 따라서 타임스탬프와 만료 기간은 웹
개발자가 WritableStreamDefaultWriter.ready를
신경 쓸 때만 효과적으로 동작합니다.
sendDatagrams는
WebTransport
객체 transport와
WebTransportDatagramsWritable
객체 writable을 받아,
네트워크 작업을 큐에 추가하여 transport로 다음 절차를
실행합니다:
-
queue를 writable.
[[OutgoingDatagramsQueue]]의 복사본으로 설정합니다.참고: 위 복사와 네트워크 작업 큐잉은 최적화할 수 있습니다.
-
maxSize를 transport.
[[Datagrams]].[[OutgoingMaxDatagramSize]]로 설정합니다. -
duration을 transport.
[[Datagrams]].[[OutgoingDatagramsExpirationDuration]]로 설정합니다. -
duration이 null이면, duration을 구현 정의 값으로 설정합니다.
-
다음 단계를 병렬로 실행합니다:
-
queue가 비어 있지 않은 동안:
-
bytes, timestamp, promise를 queue의 첫 번째 요소로 설정합니다.
-
timestamp로부터 duration 밀리초 이상 경과했다면:
-
queue의 첫 번째 요소를 제거합니다.
-
네트워크 작업을 큐에 추가하여 transport로 promise를 undefined로 resolve합니다.
-
-
그렇지 않으면, 이 루프를 종료합니다.
-
-
transport.
[[State]]가"connected"가 아니면 반환합니다. -
queue가 비어 있지 않은 동안:
-
bytes, timestamp, promise를 queue의 첫 번째 요소로 설정합니다.
-
bytes 길이 ≤ maxSize이면:
-
bytes를 즉시 네트워크에 보낼 수 없다면 이 루프를 종료합니다.
-
데이터그램 보내기를 transport.
[[Session]]과 bytes로 실행합니다.
-
-
queue의 첫 번째 요소를 제거합니다.
-
네트워크 작업을 큐에 추가하여 transport로 promise를 undefined로 resolve합니다.
-
-
User agent는 WebTransport
객체의
[[State]]
값이 "connecting" 또는 "connected"일 때, 관련된 sendDatagrams 알고리즘을
send-order rules에 의해 결정된
일부 WebTransportDatagramsWritable
객체 집합에 대해 실행해야 한다. 알고리즘이 진행할 수 있을 때, 가능한 한 빨리 실행하는 것이 좋다.
참고: 전송의 [[State]]
가 "connecting"일 때에도 datagram을 기록하는 것이 허용된다.
datagram은 [[OutgoingDatagramsQueue]]
에 저장되며, "connected" 상태와 동일하게 discard될 수 있다.
전송의 [[State]]
가 "connected"로 변경되면 대기 중인 datagram의 전송이 시작된다.
send-order rules
는 대체로 전송이 기존에 대기 중인 stream과 datagram의 전송, 그리고 앞으로 대기될 stream과 datagram의 전송과 섞여 진행될 수 있다는 규칙이다.
단, 다음 조건에서는 전송이 지연되어야 한다:
동일한 [[SendGroup]]
및 더 높은
[[SendOrder]]
값을 갖고,
에러 상태가 아니며 flow control로 차단되지 않은
stream과 datagram의 모든 바이트가 전송될 때까지는 대기하여야 한다.
참고: 기본 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]]
| 수신 datagram을 위한 ReadableStream.
|
[[ReadableType]]
| 수신 datagram에 사용되는 ReadableStreamType.
|
[[Writables]]
| 정렬된 집합의
WebTransportDatagramsWritable
스트림,
초기 값은 비어 있음.
|
[[IncomingDatagramsQueue]]
| 수신 datagram과 타임스탬프의 쌍을 담은 큐. |
[[IncomingDatagramsPullPromise]]
| pullDatagrams에 의해 설정되는 promise. 수신 datagram을 기다림. |
[[IncomingMaxBufferedDatagrams]]
| unsigned long
값으로,
수신 큐의 datagram 개수를 나타냄. 그 값을 초과하면 datagram이 큐 머리에서 버려짐.
|
[[IncomingDatagramsExpirationDuration]]
| unrestricted double
값으로,
수신 datagram의 만료 기간(밀리초)을 나타내며 또는 null.
|
[[OutgoingMaxBufferedDatagrams]]
| unsigned long
값으로,
기본 sink의 송신 큐의 datagram 개수를 나타냄. 그 값을 초과하면 backpressure가 발생함.
|
[[OutgoingDatagramsExpirationDuration]]
| unrestricted double
값으로,
송신 datagram의 만료 기간(밀리초)을 나타내며 또는 null.
|
[[OutgoingMaxDatagramSize]]
|
송신 datagram의 최대 크기를 나타내는 정수값.
최대 datagram 크기는 사용되는 프로토콜에 따라 달라집니다.
HTTP/3의 경우 [WEB-TRANSPORT-HTTP3]에서는 값이 경로 MTU의 추정치와 관련되어 있습니다. 구현별로 오버헤드를 고려하고 값을 줄입니다.
HTTP/2의 경우 [WEB-TRANSPORT-HTTP2]에서는 동등한 제한이 없습니다.
datagram 처리에는 일반적으로 전체 datagram을 메모리에 보관해야 하므로, 구현에서는 크기 제한이 있습니다. 미래의 프로토콜 확장은 모든 프로토콜 변형에 대해 이러한 크기 제한의 신호 기능을 가능하게 할 수 있습니다. |
사용자 에이전트는 [[OutgoingMaxDatagramSize]]
를 WebTransport
객체의
[[State]]
가 "connecting" 또는 "connected" 일 때 갱신할 수 있음.
WebTransportDatagramDuplexStream
과
WebTransport
transport, readable, readableType이 주어졌을 때 아래 절차를 수행한다.
-
stream을 새로운
WebTransportDatagramDuplexStream인스턴스로 만드는데, 아래와 같이 설정한다:[[Transport]]-
transport
[[Readable]]-
readable
[[ReadableType]]-
readableType
[[Writables]]-
빈 정렬된 집합.
[[IncomingDatagramsQueue]]-
빈 큐
[[IncomingDatagramsPullPromise]]-
null
[[IncomingMaxBufferedDatagrams]][[IncomingDatagramsExpirationDuration]]-
null
[[OutgoingMaxBufferedDatagrams]]-
이 구현 정의 값은 전송 데이터의 시의성과 성능을 손상시키지 않으면서, 적절한 처리량을 확보할 수 있도록 튜닝되어야 한다.
[[OutgoingDatagramsExpirationDuration]]-
null
[[OutgoingMaxDatagramSize]]
-
stream을 반환한다.
5.2. 메서드
createWritable()-
WebTransportDatagramsWritable을(를) 생성합니다.createWritable()메서드가 호출되면, 사용자 에이전트는 다음 단계를 반드시 실행해야 합니다:-
transport를 this에 연관된
WebTransport객체로 설정합니다. -
만약 transport.
[[State]]가"closed"또는"failed"이면, throwInvalidStateError를 발생시킵니다. -
만약 sendGroup이 null이 아니고, sendGroup.
[[Transport]]이 this.[[Transport]]와 다르면, throwInvalidStateError를 발생시킵니다. -
transport, sendGroup, sendOrder로 생성한
WebTransportDatagramsWritable을(를) 반환합니다.
-
5.3. 속성
readable, 타입 ReadableStream, 읽기 전용-
getter 단계는 다음과 같다:
-
this.
[[Readable]]를 반환한다.
-
incomingMaxAge, 타입 unrestricted double, nullable-
getter 단계는 다음과 같다:
setter 단계는 value가 주어졌을 때 다음과 같다:
-
만약 value가 음수거나 NaN이면, throw를 발생시키고,
RangeError를 던진다. -
value가
0이면, value를 null로 설정한다. -
this.
[[IncomingDatagramsExpirationDuration]]를 value로 설정한다.
maxDatagramSize, 타입 unsigned long, 읽기 전용-
WebTransportDatagramsWritable에 전달될 수 있는 데이터의 최대 크기. getter 단계는 this.[[OutgoingMaxDatagramSize]]를 반환한다. outgoingMaxAge, 타입 unrestricted double, nullable-
getter 단계는 다음과 같다:
setter 단계는 value가 주어졌을 때 다음과 같다:
-
만약 value가 음수거나 NaN이면, throw를 발생시키고,
RangeError를 던진다. -
value가
0이면, value를 null로 설정한다. -
this.
[[OutgoingDatagramsExpirationDuration]]를 value로 설정한다.
incomingMaxBufferedDatagrams, 타입 unsigned long-
getter 단계는 다음과 같다:
setter 단계는 value가 주어졌을 때 다음과 같다:
-
value가
1보다 작으면, value를1로 설정한다. -
this.
[[IncomingMaxBufferedDatagrams]]를 value로 설정한다.
outgoingMaxBufferedDatagrams, 타입 unsigned long-
getter 단계는 다음과 같다:
setter 단계는 value가 주어졌을 때 다음과 같다:
-
value가
1보다 작으면, value를1로 설정한다. -
this.
[[OutgoingMaxBufferedDatagrams]]를 value로 설정한다.
5.4. 절차
pullDatagrams를 하려면,
WebTransport
객체 transport가 주어졌을 때 다음 단계를 실행한다:
-
datagrams를 transport.
[[Datagrams]]로 설정한다. -
단언: datagrams.
[[IncomingDatagramsPullPromise]]가 null이다. -
queue를 datagrams.
[[IncomingDatagramsQueue]]로 설정한다. -
만약 queue가 비어 있다면:
-
datagrams.
[[IncomingDatagramsPullPromise]]에 새로운 promise를 할당한다. -
datagrams.
[[IncomingDatagramsPullPromise]]를 반환한다.
-
-
datagram과 timestamp를 queue에서 디큐(queue-dequeuing) 한 결과로 설정한다.
-
만약 datagrams.
[[ReadableType]]가"bytes"라면:-
만약 datagrams.
[[Readable]]의 현재 BYOB 요청 뷰(current BYOB request view)가 null이 아니라면:-
view를 datagrams.
[[Readable]]의 현재 BYOB 요청 뷰로 설정한다. -
view의 바이트 길이(byte length)가 datagram 크기보다 작다면, 거부된 promise와 함께
RangeError를 반환한다. -
elementSize를 TypedArray 생성자 테이블에서 view.[[TypedArrayName]]에 해당하는 요소 크기로 설정한다. 만약 view에 [[TypedArrayName]] 내부 슬롯이 없으면(DataView인 경우), elementSize를 0으로 한다.
-
elementSize가 1이 아니라면, 거부된 promise와 함께
TypeError를 반환한다.
-
-
바이트로부터 Pull을 호출하여 datagram을 datagrams.
[[Readable]]에 넣는다.
-
-
그 외의 경우:
-
chunk를
Uint8Array객체로 새로 생성하여 datagram을 나타내도록 한다. -
Enqueue(엔큐) chunk를 transport.
[[Datagrams]].[[Readable]]에 추가한다.
-
-
undefined로 resolve된 promise를 반환한다.
receiveDatagrams
알고리즘은,
WebTransport
객체 transport를 받아 다음 단계를 수행한다:
-
timestamp를 현재 시점의 타임스탬프로 설정한다.
-
queue를 datagrams.
[[IncomingDatagramsQueue]]로 설정한다. -
duration을 datagrams.
[[IncomingDatagramsExpirationDuration]]로 설정한다. -
duration이 null이면, duration을 구현 정의값으로 설정한다.
-
session을 transport.
[[Session]]로 설정한다. -
session에 받을 수 있는 datagram이 있다면 반복한다:
-
datagram을 session에서 datagram 수신의 결과로 얻는다.
-
timestamp를 현재 시점의 타임스탬프로 설정한다.
-
chunk를 datagram과 timestamp의 쌍으로 만든다.
-
Enqueue chunk를 queue에 넣는다.
-
-
toBeRemoved를 queue 길이에서 datagrams.
[[IncomingMaxBufferedDatagrams]]값을 빼서 계산한다. -
toBeRemoved가 양수면, queue에서 dequeue를 toBeRemoved번(내림 처리) 반복한다.
-
queue가 비어 있지 않은 동안 반복한다:
-
bytes와 timestamp를 queue의 첫 번째 요소에서 얻는다.
-
timestamp로부터 duration 밀리초가 지나면 queue에서 dequeue한다.
-
그 외에는 break로 반복문을 종료한다.
-
-
queue가 비어 있지 않고 datagrams.
[[IncomingDatagramsPullPromise]]가 null이 아니라면:-
bytes와 timestamp를 queue에서 dequeue한다.
-
promise를 datagrams.
[[IncomingDatagramsPullPromise]]가 가리키는 값으로 설정한다. -
datagrams.
[[IncomingDatagramsPullPromise]]값을 null로 설정한다. -
네트워크 작업 큐에 추가 알고리즘을 transport와 함께 실행하고 아래 단계를 수행한다:
-
chunk를
Uint8Array객체로 새로 만들고 bytes를 나타내도록 한다. -
Enqueue chunk를 datagrams.
[[Readable]]에 넣는다. -
promise 해제를 promise와 undefined로 수행한다.
-
-
User agent는 WebTransport
객체의
[[State]]
값이 "connected"일 때,
알고리즘이 진행할 수 있을 때 가능한 한 빨리 receiveDatagrams를 실행하는 것이 좋다.
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 optional BufferSource );context 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 = {}); /* a ReadableStream of WebTransportBidirectionalStream objects */options readonly attribute ReadableStream incomingBidirectionalStreams ;Promise <WebTransportSendStream >createUnidirectionalStream (optional WebTransportSendStreamOptions = {}); /* a ReadableStream of WebTransportReceiveStream objects */options readonly attribute ReadableStream incomingUnidirectionalStreams ;WebTransportSendGroup createSendGroup ();static readonly attribute boolean supportsReliableOnly ; };enum {WebTransportReliabilityMode ,"pending" ,"reliable-only" , };"supports-unreliable"
6.1. 내부 슬롯
WebTransport
객체는 다음과 같은 내부 슬롯을 가진다.
| 내부 슬롯 | 설명 (비규범적) |
|---|---|
[[SendStreams]]
| 이 WebTransport가
소유하는
WebTransportSendStream
들의 정렬된 집합.
|
[[ReceiveStreams]]
| 이 WebTransport가
소유하는
WebTransportReceiveStream
들의 정렬된 집합.
|
[[IncomingBidirectionalStreams]]
| ReadableStream
으로 이루어진 WebTransportBidirectionalStream
객체들.
|
[[IncomingUnidirectionalStreams]]
| ReadableStream
으로 이루어진 WebTransportReceiveStream
들.
|
[[State]]
| 전송의 상태를 나타내는 enum. 값은
"connecting",
"connected", "draining", "closed", "failed"
중 하나.
|
[[Ready]]
| 연관된 WebTransport session 이 설정됨 상태가 되면 fulfill되고, 설정 과정 이 실패하면 reject되는 promise. |
[[Reliability]]
| 첫 홉이 신뢰성 없는(UDP) 전송을 지원하는지, 아니면 신뢰성 있는(TCP fallback) 전송만 가능한지 나타내는
WebTransportReliabilityMode.
연결이 설정되기 전에는 "pending" 상태.
|
[[CongestionControl]]
| 애플리케이션이 처리량 또는 저지연 최적화 혼잡 제어 알고리즘을 요청했고, user agent가 이를 만족시켰는지 나타내는
WebTransportCongestionControl.
또는 "default".
|
[[AnticipatedConcurrentIncomingUnidirectionalStreams]]
| 애플리케이션이 서버가 생성할 것으로 예상하는 동시에 열린 수신 단방향 스트림 개수 또는 null. |
[[AnticipatedConcurrentIncomingBidirectionalStreams]]
| 애플리케이션이 서버가 생성할 것으로 예상하는 양방향 스트림의 개수 또는 null. |
[[ResponseHeaders]]
| Headers
객체 또는 null. 초기 값은 null.
|
[[Protocol]]
| 서버가 선택한 애플리케이션 레벨 프로토콜을 나타내는 문자열(있다면). 초기 값은 빈 문자열. |
[[Closed]]
| 연관된 WebTransport
객체가 정상적으로 종료되면 fulfill,
비정상 또는 초기화 실패시 reject되는 promise.
|
[[Draining]]
| 연관된 WebTransport session 이 draining 상태가 되면 fulfill되는 promise. |
[[Datagrams]]
| WebTransportDatagramDuplexStream
객체.
|
[[Session]]
| 이 WebTransport
객체에 대한
WebTransport session 또는 null.
|
[[NewConnection]]
| "no" 또는 "yes-and-dedicated".
|
[[RequireUnreliable]]
| UDP가 필수인지 여부를 나타내는 boolean 값. |
6.2. 생성자
WebTransport()
생성자가 호출되면,
UA는 아래 단계를 따라야 한다:
-
baseURL을 this의 관련 설정 객체의 API 기본 URL로 한다.
-
만약 url이 failure라면, throw를 발생시키고
SyntaxError예외를 던진다. -
만약 url의 스킴이
https가 아니라면, throw를 발생시키고SyntaxError예외를 던진다. -
만약 url의 프래그먼트가 null이 아니라면, throw를 발생시키고
SyntaxError예외를 던진다. -
newConnection을
options의allowPooling값이 true이면 "no", 그렇지 않으면 "yes-and-dedicated"로 한다. -
serverCertificateHashes를
options의serverCertificateHashes로 한다. -
만약 newConnection이 "
no"이고 serverCertificateHashes가 비어있지 않다면, throw를 발생시키고NotSupportedError예외를 던진다. -
requireUnreliable을
options의requireUnreliable로 한다. -
congestionControl을
options의congestionControl로 한다. -
만약 congestionControl이
"default"가 아니고, 사용자 에이전트가 congestionControl에 최적화된 혼잡 제어 알고리즘을 지원하지 않는 경우 [RFC9002] Section 7에 따라, congestionControl을"default"로 설정한다. -
만약 protocols에서 같은 값이 중복되거나, WebTransport 프로토콜이 정의한 협상된 애플리케이션 프로토콜 값의 요건에 맞지 않거나, 동일인코딩 길이가 0이거나 512를 초과하면, throw를 발생시키고
SyntaxError예외를 던진다. [WEB-TRANSPORT-OVERVIEW] Section 3.1. -
anticipatedConcurrentIncomingUnidirectionalStreams를
options의anticipatedConcurrentIncomingUnidirectionalStreams로 한다. -
anticipatedConcurrentIncomingBidirectionalStreams를
options의anticipatedConcurrentIncomingBidirectionalStreams로 한다. -
datagramsReadableType을
options의datagramsReadableType로 한다. -
incomingDatagrams를 새로운
ReadableStream으로 한다. -
transport를 새로 만든
WebTransport객체로, 구성 값은 다음과 같다:[[SendStreams]]-
비어있는 정렬된 집합(ordered set)
[[ReceiveStreams]]-
비어있는 정렬된 집합(ordered set)
[[IncomingBidirectionalStreams]][[IncomingUnidirectionalStreams]][[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
-
transport.
[[Datagrams]]를 생성 결과로,WebTransportDatagramDuplexStream, transport, incomingDatagrams, datagramsReadableType로서 설정한다. -
pullDatagramsAlgorithm을 pullDatagrams를 transport에 대해 실행하는 동작으로 한다.
Note: datagrams에서는 64 kibibytes 버퍼 사용이 권장된다. WebTransport datagram 프레임의 실질적인 최대 크기는 QUIC의 datagram 최대 프레임 크기에 따라 상한이 64 kibibyte이다. (See [QUIC-DATAGRAM] Section 3) 이는 datagram이 버퍼보다 커서 스트림이 에러나는 상황을 예방한다.
-
datagramsReadableType이
"bytes"인 경우, 바이트 읽기 지원으로 설정 incomingDatagrams에 pullAlgorithm 을 pullDatagramsAlgorithm으로, highWaterMark 를 0으로 설정. 그 외에는 설정 및 pullAlgorithm을 pullDatagramsAlgorithm으로, highWaterMark를 0으로 설정. -
pullBidirectionalStreamAlgorithm을 pullBidirectionalStream 을 transport에 대해 실행하는 동작으로 한다.
-
설정 transport.
[[IncomingBidirectionalStreams]]에 pullAlgorithm을 pullBidirectionalStreamAlgorithm으로, highWaterMark를 0으로 설정. -
pullUnidirectionalStreamAlgorithm을 pullUnidirectionalStream 을 transport에 대해 실행하는 동작으로 한다.
-
설정 transport.
[[IncomingUnidirectionalStreams]]에 pullAlgorithm을 pullUnidirectionalStreamAlgorithm으로, highWaterMark를 0으로 설정. -
client를 transport의 관련 설정 객체로 한다.
-
origin을 client의 origin으로 한다.
-
request를 새로운 request로 하며, URL은 url, client는 client, service-workers mode는 "
none", referrer는 "no-referrer", mode는 "webtransport", credentials mode는 "omit", cache mode는 "no-store", policy container는 client의 policy container, destination은 "", origin은 origin, WebTransport-hash list는 serverCertificateHashes이고 redirect mode는 "error"이다.Note: 리다이렉트는 따라가지 않는다. 리다이렉션으로 인한 네트워크 에러는 의도적으로 다른 네트워크 에러와 구분되지 않는다. 크로스-오리진 환경에서는 일반적으로 CORS로 차단되는 정보를 드러낼 수 있다. same-origin에서도 핸드셰이크를 정보 전달 경로로 남용할 우려가 있다.
-
request의 method를 "
CONNECT"로 하고, method에 연결된:protocolpseudo-header는"webtransport"로 한다. -
headers를 새로운
Headers객체로 하며, 채워진options["headers"] 값을 사용한다. -
requestHeaders를 새로운
Headers객체로 하며 헤더 목록(header list)은 request의 header list, guard는 "request"이다. -
headers의 header list의 각 header마다:
-
ascii 소문자 header의 이름(name)이 "
wt-available-protocols"이면,TypeError를 던진다. -
append header를 requestHeaders에 추가한다.
Note: 헤더는 Fetch의 forbidden request-header 제한을 받는다.
-
-
protocols가 비어있지 않다면, 구조화 필드 값(set a structured field value)을 (
WT-Available-Protocols, 구조화 헤더 리스트가 protocols의 구조화 헤더 문자열(string) 항목이 순서대로 포함됨)로 request의 header list에 설정한다. -
Fetch request를 실행하며, useParallelQueue는 true, processResponse 는 response가 주어질 때 다음 단계로 설정:
-
WebTransport fetch response 처리를 response와 transport로 실행한다.
-
-
transport를 반환한다.
-
transport를
WebTransport로, request에 대응하는 객체로 설정한다. -
url을 request의 current URL로 설정한다.
-
newConnection을 transport.
[[NewConnection]]값으로 설정한다. -
requireUnreliable을 transport.
[[RequireUnreliable]]값으로 설정한다. -
webTransportHashes를 request의 WebTransport-hash list 값들로 설정한다.
-
connection을 obtaining a connection 알고리즘을 networkPartitionKey, url, false, newConnection, requireUnreliable, webTransportHashes로 실행한 결과로 설정한다.
-
connection이 failure면, failure 반환.
-
connection에서 첫 SETTINGS 프레임을 받을 때까지 대기, settings를 SETTINGS 프레임을 나타내는 딕셔너리로 설정.
-
settings에
SETTINGS_ENABLE_CONNECT_PROTOCOL(0x08, Section 3 of [RFC8441] (HTTP/2); 0x08, Section 3 of [RFC9220] (HTTP/3)) 값이 1이 아니라면, failure 반환. -
settings가 서버의 WebTransport 지원을 나타내지 않으면, failure 반환. [WEB-TRANSPORT-OVERVIEW] Section 4.1.
-
HTTP/3에서는
SETTINGS_WT_MAX_SESSIONS값이 0 초과,SETTINGS_H3_DATAGRAM값이 1이어야 함. [WEB-TRANSPORT-HTTP3] Section 3.1. -
HTTP/2에서는
SETTINGS_ENABLE_CONNECT_PROTOCOL위의 값이 서버의 지원임을 이미 표시. [WEB-TRANSPORT-HTTP2] Section 3.1.
참고:
SETTINGS_WT_MAX_SESSIONS는 IETF에서 변경될 수 있으며SETTINGS_ENABLE_WEBTRANSPORT로 바뀔 수도 있음. -
-
connection 을 반환한다.
WebTransport
transport를 받아 다음 단계를 수행한다:
-
response가 network error면, 남은 단계 중단, queue a network task를 transport로 실행하여 아래 단계 수행:
-
transport.
[[State]]가"closed"나"failed"면 중단. -
error를 새 WebTransportError로 만들고,
source값을"session"으로 한다. -
Cleanup transport에 error로 수행.
-
-
connection을 response에 대응하는 underlying connection으로 설정.
-
서버의 response를 사용해 [WEB-TRANSPORT-OVERVIEW] Section 4.1 의 제한에 따라 WebTransport session 설정을 connection에 수행하고, session을 결과 WebTransport session으로 설정. 결과 underlying transport stream을 session의 CONNECT stream이라 한다.
참고: 이 단계에서 [QUIC-DATAGRAM]의 transport parameter 교환도 완료.
-
이 전 단계가 실패하면 나머지 중단, queue a network task를 transport로 실행하여 아래 단계를 수행:
-
transport.
[[State]]가"closed"또는"failed"면 중단. -
error를 새 WebTransportError로 만들고,
source를"session"으로 설정. -
Cleanup transport에 error로 수행.
-
-
UA가 둘 이상의 혼잡 제어 알고리즘을 지원한다면, transport의
[[CongestionControl]]값에 맞는 것을 connection 데이터 송신에 선택한다. -
queue a network task를 transport로 실행하여 아래 단계 수행:
-
Assert: this의
[[Datagrams]]에[[OutgoingMaxDatagramSize]]가 정수임을 확인. -
transport.
[[State]]가"connecting"이 아니면: -
transport.
[[State]]값을"connected"로 설정. -
transport.
[[Session]]값을 session으로 설정. -
responseHeaders를 response의 header list의 복사본으로 설정.
-
삭제 "
wt-protocol"를 responseHeaders에서 제거. -
transport.
[[ResponseHeaders]]값을 새Headers객체로 설정하고, header list는 responseHeaders, guard는 "immutable"로 한다. -
transport.
[[Protocol]]값을 negotiated application protocol이 있으면 그 문자열 값으로, 없으면""로 설정 ([WEB-TRANSPORT-OVERVIEW] Section 3.1 참고). -
connection이 HTTP/3 연결이면, transport.
[[Reliability]]값을"supports-unreliable"로 설정. -
connection이 HTTP/2 연결이면 ([WEB-TRANSPORT-HTTP2]), transport의
[[Reliability]]값을"reliable-only"로 설정.
-
WebTransport
객체 transport를 받아
아래 단계 실행.
-
transport.
[[State]]가"connecting"이면, transport.[[Ready]]가 fulfill될 때 아래 절차를 수행:-
pullBidirectionalStream을 transport로 수행한 결과 반환.
-
-
transport.
[[State]]가"connected"가 아니면, rejected promise를InvalidStateError로 반환. -
session을 transport.
[[Session]]으로 설정한다. -
p를 새 promise로 설정.
-
병렬로 아래 단계를 실행:
-
session에 수신 대기 가능한 양방향 스트림 생길 때까지 대기.
-
internalStream을 양방향 스트림 수신에서 session으로 받음.
-
queue a network task를 transport로 실행하여 아래 단계를 수행:
-
stream을 WebTransportBidirectionalStream 생성으로, internalStream과 transport를 전달하여 만든 결과로 설정.
-
Enqueue stream을 transport.
[[IncomingBidirectionalStreams]]에 넣는다. -
Resolve p 값을 undefined로 해제.
-
-
-
p를 반환한다.
WebTransport
객체 transport를 받아
아래 단계 실행.
-
transport.
[[State]]가"connecting"이면, transport.[[Ready]]가 fulfill될 때 아래 절차를 수행:-
pullUnidirectionalStream을 transport로 수행한 결과 반환.
-
-
transport.
[[State]]가"connected"가 아니면, rejected promise를InvalidStateError로 반환. -
session을 transport.
[[Session]]로 설정한다. -
p를 새 promise로 설정.
-
병렬로 아래 단계를 실행:
-
session에 수신 대기 가능한 단방향 스트림 생길 때까지 대기.
-
internalStream을 단방향 스트림 수신에서 session으로 받음.
-
queue a network task를 transport로 실행하여 아래 단계를 수행:
-
stream을 WebTransportReceiveStream 생성으로, internalStream과 transport를 전달하여 만든 결과로 설정.
-
Enqueue stream을 transport.
[[IncomingUnidirectionalStreams]]에 넣는다. -
Resolve p 값을 undefined로 해제.
-
-
-
p를 반환한다.
6.3. 속성
ready, Promise<undefined> 타입, readonlyclosed, Promise<WebTransportCloseInfo> 타입, readonly-
얻을 때 this의
[[Closed]]를 반환해야 한다. draining, Promise<undefined> 타입, readonly-
얻을 때 this의
[[Draining]]를 반환해야 한다. datagrams, WebTransportDatagramDuplexStream 타입, readonly-
이 세션을 통해 데이터그램을 송수신하는 단일 duplex 스트림.
datagrams속성의 getter 단계는 다음과 같다:-
this의
[[Datagrams]]를 반환.
-
incomingBidirectionalStreams, ReadableStream 타입, readonly-
서버로부터 수신된
ReadableStream내WebTransportBidirectionalStream들의 목록을 반환함.Note: 수신 스트림에 이미 데이터가 있는지는 서버 동작에 따라 다를 수 있음.
incomingBidirectionalStreams속성 getter 단계: incomingUnidirectionalStreams, ReadableStream 타입, readonly-
서버로부터 수신된 각
ReadableStream의 단방향 스트림WebTransportReceiveStream로 이루어짐.Note: 수신 스트림에 이미 데이터가 있는지는 서버 동작에 따라 다를 수 있음.
incomingUnidirectionalStreams속성 getter 단계: reliability, WebTransportReliabilityMode 타입, readonly-
연결이 신뢰성 없는(UDP) 전송을 지원하는지 또는 신뢰성 있는(TCP fallback) 전송만 지원하는지 여부. 연결이 설정될 때까지
"pending"을 반환. getter 단계는 this의[[Reliability]]를 반환함. congestionControl, WebTransportCongestionControl 타입, readonly-
생성자에서 요청했고 사용자 에이전트가 충족시켜준 경우 처리량 최적화 또는 저지연 최적화 혼잡 제어 알고리즘에 대한 애플리케이션의 선호도. 요청했으나 충족되지 않은 경우
"default". getter 단계는 this의[[CongestionControl]]를 반환. supportsReliableOnly, boolean 타입, readonly-
사용자 에이전트가 오직 신뢰할 수 있는 WebTransport 세션만 지원하는 연결을 지원하면 true, 아니면 false.
anticipatedConcurrentIncomingUnidirectionalStreams, unsigned short 타입, nullable-
애플리케이션이 서버가 개설할 것으로 예상하는 동시에 열린 수신 단방향 스트림 수를 명시적으로 지정할 수 있음. null이 아니면, 사용자 에이전트는 서버와의 협상에서
[[AnticipatedConcurrentIncomingUnidirectionalStreams]]를 고려하여 향후 왕복시간을 줄이기 위해 노력해야 함.getter 단계는 this의
[[AnticipatedConcurrentIncomingUnidirectionalStreams]]를 반환.setter 단계는 value가 주어질 경우 this의
[[AnticipatedConcurrentIncomingUnidirectionalStreams]]에 value를 할당. anticipatedConcurrentIncomingBidirectionalStreams, unsigned short 타입, nullable-
애플리케이션이 서버가 개설할 것으로 예상하는 동시에 열린 양방향 스트림 수를 명시적으로 지정할 수 있음. null이 아니면 사용자 에이전트는 서버와의 협상에서
[[AnticipatedConcurrentIncomingBidirectionalStreams]]를 고려해야 함.getter 단계는 this의
[[AnticipatedConcurrentIncomingBidirectionalStreams]]를 반환.setter 단계는 value가 주어질 경우 this의
[[AnticipatedConcurrentIncomingBidirectionalStreams]]에 value를 할당.
Note: anticipatedConcurrentIncomingUnidirectionalStreams
또는
anticipatedConcurrentIncomingBidirectionalStreams를
설정해도
애플리케이션이 예상한 수 만큼 스트림을 반드시 수신할 것이라는 보장은 없음.
responseHeaders, 타입 Headers, 읽기 전용, 널 허용-
WebTransport 세션이 설정된 후, 서버가 설정한 어플리케이션 레벨 응답 헤더를 보관(있을 경우)합니다. 초기값은 null. getter 단계는 this의
[[ResponseHeaders]]값을 반환합니다. protocol, 타입 DOMString, 읽기 전용-
WebTransport 세션이 설정되고
protocols생성자 옵션에서 비어있지 않은 배열을 제공했다면, 서버가 선택한 어플리케이션 프로토콜을 반환(있을 경우). 아니면 빈 문자열 반환. getter 단계는 this의[[Protocol]]값을 반환합니다.
6.4. 메서드
close(closeInfo)-
WebTransport 객체에 연결된 WebTransport 세션을 종료합니다.
close가 호출되면, 사용자 에이전트는 다음 단계를 실행해야 합니다:
-
transport를 this로 설정합니다.
-
transport.
[[State]]값이"closed"또는"failed"이면 단계 종료. -
transport.
[[State]]값이"connecting"이면:-
error를 새 WebTransportError로 만듭니다.
source값을"session"으로 설정합니다. -
Cleanup transport에 error로 실행합니다.
-
단계 종료.
-
-
session을 transport.
[[Session]]로 설정합니다. -
code를 closeInfo.
closeCode로 설정합니다. -
reasonString을 code unit prefix의 최대 길이로, closeInfo.
reason값에서 UTF-8 인코딩 길이가 1024를 넘지 않도록 구함. -
reason을 reasonString을 UTF-8로 인코딩한 값으로 설정합니다.
-
병렬로 terminate를 session, code, reason과 함께 수행합니다.
참고: 이 단계는 전송 중단 또는 수신 중단도 WebTransport 스트림에 대해 함께 처리하며, transport.
[[SendStreams]]와[[ReceiveStreams]]에 적용됩니다. -
Cleanup transport에
AbortError및 closeInfo로 수행.
-
getStats()-
이
WebTransport의 하위 연결 에 대한 통계 정보를 비동기로 조회합니다.getStats가 호출되면, 사용자 에이전트는 다음 단계를 수행해야 합니다:
-
transport를 this로 설정합니다.
-
p를 새 promise로 설정합니다.
-
transport.
[[State]]값이"failed"라면 reject p를InvalidStateError와 함께 반환하고 단계 종료. -
아래 단계를 병렬로 수행합니다:
-
transport.
[[State]]값이"connecting"이면, 값이 변경될 때까지 대기합니다. -
transport.
[[State]]값이"failed"면, queue a network task를 transport로 실행한 후 reject p를InvalidStateError로 반환하고 단계 종료합니다. -
transport.
[[State]]값이"closed"면, queue a network task 를 transport로 실행한 후 resolve p를 해당 연결의 최신 통계 정보로 반환합니다. 구체적인 수집 시점은 구현 정의입니다. -
gatheredStats를 list로, 연결의 하위 연결에 맞는 통계 정보를 수집해
WebTransportConnectionStats와WebTransportDatagramStats구조체의 딕셔너리 멤버에 정확하게 채울 수 있도록 준비합니다. -
queue a network task를 transport로 실행하여 아래 단계를 수행합니다:
-
stats를 새
WebTransportConnectionStats객체로 설정. -
datagramStats를 새
WebTransportDatagramStats객체로 설정. -
stats["
datagrams"] 값을 datagramStats로 설정합니다. -
사용자 에이전트가 노출을 원하는 stats와 datagramStats의 각 멤버에 대해, set을 gatheredStats의 해당 entry로 설정합니다.
-
Resolve p를 stats로 해제합니다.
-
-
-
p를 반환합니다.
-
exportKeyingMaterial(BufferSource label, optional BufferSource context)-
이
WebTransport의 TLS 세션에서 고유하게 연관된 TLS Keying Material Exporter 로부터 키 재료를 내보냅니다. 하위 연결을 사용합니다.exportKeyingMaterial가 호출되면, 사용자 에이전트는 다음 단계를 수행해야 합니다:
-
transport를 this로 한다.
-
labelLength를 label.바이트 길이로 한다.
-
labelLength가 255보다 크면, 거부된 promise와 함께
RangeError를 반환한다. -
contextLength를 0으로 한다.
-
context가 주어졌다면, contextLength를 context.바이트 길이로 한다.
-
contextLength가 255보다 크면, 거부된 promise와 함께
RangeError를 반환한다. -
p를 새로운 promise로 한다.
-
아래의 단계를 병렬로 실행하되, 아래 조건에서 중단(abort)된다: transport의
[[State]]가"closed"또는"failed"가 되면, 네트워크 작업(queue a network task)을 transport에 대해 큐잉하여 reject p +InvalidStateError:-
keyingMaterial을
Uint8Array로 하며, TLS key exporter를 호출해서 생성한다. (자세한 내용은 [WEB-TRANSPORT-OVERVIEW] Section 4.1 을 참고), labelLength, label, contextLength, 그리고 context가 있으면 함께 넘긴다. -
네트워크 작업을 큐잉(queue a network task) 하여 transport와 함께 p를 resolve하고 keyingMaterial을 넘긴다.
-
-
p를 반환한다.
-
createBidirectionalStream()-
송신용 양방향 스트림을 위한
WebTransportBidirectionalStream객체를 생성합니다. 스트림이 단순 생성되었다고 해서 즉시 피어가 인지하게 되는 것은 아닙니다. 데이터를 실제로 보내기 전까지는 서버도 스트림의 존재를 알지 못할 수 있습니다.참고: 스트림에 실제 데이터가 보내지기 전까지 서버는 스트림의 존재를 반드시 인지하지 않습니다.
createBidirectionalStream 호출 시 사용자 에이전트는 다음 단계를 수행해야 합니다:-
this.
[[State]]값이"closed"또는"failed"이면, rejected promise를InvalidStateError로 반환합니다. -
sendGroup이 null이 아니고, sendGroup.
[[Transport]]값이 this가 아니면, throwInvalidStateError발생. -
waitUntilAvailable을
options의waitUntilAvailable로 설정. -
p를 새 promise로 설정합니다.
-
transport를 this로 설정합니다.
-
아래 단계를 병렬로 수행. 단 abort when transport의
[[State]]값이"closed"또는"failed"가 되면, queue a network task를 transport로 실행, reject p를InvalidStateError로 처리:-
streamId를 transport.
[[Session]]에 대해 유효하고 고유한 스트림 ID로 새로 만듭니다. [QUIC] Section 19.11 참고. 고갈로 인해 즉시 사용 불가능하다면 waitUntilAvailable이 true면 대기, false면, queue a network task를 transport로 실행해 reject p를QuotaExceededError(requested/quota 모두 null). -
internalStream을 양방향 스트림 생성 알고리즘을, transport.
[[Session]]과 streamId를 넘겨 실행한 결과로 설정합니다. -
queue a network task 를 transport로 실행해 다음을 수행:
-
transport.
[[State]]값이"closed"또는"failed"면, reject p를InvalidStateError와 함께 반환, 단계 종료. -
stream을 WebTransportBidirectionalStream 생성 알고리즘 결과로, internalStream, transport, sendGroup, sendOrder를 넘겨 실행했습니다.
-
Resolve p를 stream으로 처리.
-
-
-
p를 반환합니다.
-
createUnidirectionalStream()-
송신용 단방향 스트림을 위한
WebTransportSendStream객체를 생성합니다. 스트림이 단순 생성되었다고 해서 즉시 서버가 인지하게 되는 것은 아닙니다. 데이터가 실제로 보내지기 전까지는 서버도 스트림의 존재를 알지 못할 수 있습니다.참고: 데이터가 실제로 보내지기 전까지 서버는 스트림의 존재를 반드시 인지하지 않습니다.
createUnidirectionalStream() 호출 시 사용자 에이전트는 다음 단계를 수행해야 합니다:-
this.
[[State]]값이"closed"또는"failed"이면, rejected promise를InvalidStateError로 반환합니다. -
sendGroup이 null이 아니고, sendGroup.
[[Transport]]값이 this가 아니면, throwInvalidStateError발생. -
waitUntilAvailable을
options의waitUntilAvailable로 설정. -
p를 새 promise로 설정합니다.
-
transport를 this로 설정합니다.
-
아래 단계를 병렬로 수행. 단 abort when transport의
[[State]]값이"closed"또는"failed"가 되면, queue a network task를 transport로 실행, reject p를InvalidStateError로 처리:-
streamId를 transport.
[[Session]]에 대해 유효하고 고유한 스트림 ID로 새로 만듭니다. [QUIC] Section 19.11 참고. 고갈로 즉시 사용 불가면 waitUntilAvailable이 true면 대기, false면, queue a network task를 transport로 실행하여 reject p를QuotaExceededError로 처리. -
internalStream을 단방향 스트림 생성 알고리즘 결과로, transport.
[[Session]]과 streamId를 넘겨 실행합니다. -
queue a network task 를 transport로 실행해 다음을 수행:
-
transport.
[[State]]값이"closed"또는"failed"면, reject p를InvalidStateError로 반환, 단계 종료. -
stream을 WebTransportSendStream 생성 알고리즘 결과로, internalStream, transport, sendGroup, sendOrder를 넘겨 실행합니다.
-
Resolve p를 stream으로 처리.
-
-
-
p를 반환합니다.
-
createSendGroup()-
WebTransportSendGroup을 생성합니다.createSendGroup() 메서드가 호출되면, 사용자 에이전트는 다음 단계를 수행해야 합니다:-
this.
[[State]]값이"closed"또는"failed"면 throwInvalidStateError를 발생시킵니다. -
WebTransportSendGroup 생성 알고리즘 결과로, this를 넘겨 실행한 결과를 반환합니다.
-
6.5. 절차
WebTransport
transport와 error
그리고 선택적으로 closeInfo로 수행하려면, 다음 단계를 실행:
-
sendStreams 를 transport.
[[SendStreams]]의 복사본으로 설정. -
receiveStreams 를 transport.
[[ReceiveStreams]]의 복사본으로 설정. -
outgoingDatagramWritables 를 transport.
[[Datagrams]].[[Writables]]로 설정. -
incomingDatagrams 를 transport.
[[Datagrams]].[[Readable]]로 설정. -
ready를 transport.
[[Ready]]로 설정. -
closed를 transport.
[[Closed]]로 설정. -
incomingBidirectionalStreams를 transport.
[[IncomingBidirectionalStreams]]로 설정. -
incomingUnidirectionalStreams를 transport.
[[IncomingUnidirectionalStreams]]로 설정. -
transport.
[[SendStreams]]를 빈 set으로 설정. -
transport.
[[ReceiveStreams]]를 빈 set으로 설정. -
transport.
[[Datagrams]].[[OutgoingDatagramsQueue]]를 빈 queue로 설정. -
transport.
[[Datagrams]].[[IncomingDatagramsQueue]]를 빈 queue로 설정. -
closeInfo가 주어지면, transport.
[[State]]를"closed"로, 아니면 transport.[[State]]를"failed"로 설정. -
For each stream in sendStreams에 대해 다음 수행:
-
stream.
[[PendingOperation]]가 null이 아니면 stream.[[PendingOperation]]을 error로 reject. -
Error stream을 error로 처리.
-
-
For each stream in receiveStreams: error stream을 error로 처리.
Note: 스크립트 작성자가 Promise resolve에서 동기적으로 코드를 주입할 수 있기 때문에, 여기서 transport의 값은 예측할 수 없이 변할 수도 있어, 이후로는 transport를 조작하지 않는다. 이 동작을 호출하는 로직에서도 마찬가지 주의가 필요하다.
-
closeInfo가 주어지면 다음을 실행:
-
그 외에는,
-
Reject closed를 error로.
-
closed.
[[PromiseIsHandled]]를 true로 설정. -
Reject ready를 error로.
-
ready.
[[PromiseIsHandled]]를 true로 설정. -
Error incomingBidirectionalStreams 를 error로.
-
Error incomingUnidirectionalStreams를 error로.
-
각 writable in outgoingDatagramWritables에 대해 error writable을 error로 처리.
-
Error incomingDatagrams를 error로.
-
queue a network task을
WebTransport
transport와
일련의 단계 steps로 실행하려면 다음을 수행:
-
Queue a global task를 network task source에 넣고, transport의 relevant global object에서 steps를 실행.
6.6. 클라이언트가 시작하지 않은 세션 종료
WebTransport
transport와 연결된 WebTransport session이
종료될 때,
선택적으로 code 및 reasonBytes와 함께 다음 단계를 실행한다:
-
Queue a network task를 transport에 대해 다음 단계 실행:
-
transport.
[[State]]가"closed"또는"failed"면 이 단계를 중단한다. -
error를 새로 생성한
WebTransportError로,source는"session"로 한다. -
closeInfo를 new
WebTransportCloseInfo로 생성한다. -
code가 주어진 경우, closeInfo의
closeCode에 code를 설정한다. -
reasonBytes가 주어진 경우, closeInfo의
reason에 reasonBytes의 UTF-8 해독값을 할당한다.Note: reasonBytes에는 언어나 방향 정보가 없다. First-strong 규칙으로 표시 방향을 추론할 수 있다.
-
Cleanup transport를 error와 closeInfo와 함께 처리한다.
-
WebTransport
transport의 underlying connection에 연결 오류가 발생할 때 다음 단계를 실행:
-
Queue a network task를 transport로 다음 단계 실행:
-
transport.
[[State]]가"closed"또는"failed"면 이 단계를 중단한다. -
error를 새로 생성한
WebTransportError로,source는"session"로 한다. -
Cleanup transport를 error와 함께 처리한다.
-
6.7. 컨텍스트 정리 절차
이 명세서는 context cleanup
steps를 다음과 같이 정의한다. 단,
WebTransport
transport가 주어진다:
-
transport.
[[State]]가"connected"이면, 다음을 수행한다:-
transport.
[[State]]를"failed"로 설정한다. -
병렬로(In parallel), terminate를 수행하여 transport.
[[Session]]을 종료한다. -
네트워크 작업을 큐에 넣어 transport로 다음 단계를 실행한다:
-
error를 새로 생성된
WebTransportError로 두되, 그source는"session"으로 한다. -
Cleanup을 transport와 error로 수행한다.
-
-
-
transport.
[[State]]가"connecting"이면, transport.[[State]]를"failed"로 설정한다.이는 워커에서도 수행되어야 한다. 다음을 참조: #127 및 whatwg/html#6731.
6.8. 가비지 컬렉션(Garbage Collection)
WebTransport
객체의 [[State]]
가 "connecting"일 때는,
[[IncomingBidirectionalStreams]],
[[IncomingUnidirectionalStreams]],
어떤
WebTransportReceiveStream,
또는 [[Datagrams]].[[Readable]]
이 locked 상태이거나,
ready,
draining,
closed
프로미스가 관찰 중인 경우에는 garbage collection 대상이 되어서는 안 된다.
WebTransport
객체의 [[State]]
가 "connected"일 때는,
[[IncomingBidirectionalStreams]],
[[IncomingUnidirectionalStreams]],
어떤
WebTransportReceiveStream,
또는 [[Datagrams]].[[Readable]]
이 locked 상태이거나,
draining
또는 closed
프로미스가 관찰 중인 경우에는 garbage collection 대상이 되어서는 안 된다.
WebTransport
객체의 [[State]]
가 "draining"일 때는,
[[IncomingBidirectionalStreams]],
[[IncomingUnidirectionalStreams]],
어떤
WebTransportReceiveStream,
또는 [[Datagrams]].[[Readable]]
이 locked 상태이거나,
closed
프로미스가 관찰 중인 경우에는 garbage collection 대상이 되어서는 안 된다.
established된 WebTransport session이 있고
네트워크 전송 대기 중인 데이터가 있는 WebTransport
객체(여기에는 [[Datagrams]].[[OutgoingDatagramsQueue]]
에 포함된 데이터그램이 포함됨)는 garbage collection 대상이 되어서는 안 된다.
WebTransport
객체가 garbage collection의 대상이 되었는데 underlying connection
이 아직 열려 있는 경우, 사용자 에이전트는 반드시
Application
Error Code 0 및 Application Error Message ""로 WebTransport session을 종료
해야 한다.
6.9. 구성(Configuration)
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 세션이 pool될 수 있음, 즉, 하위 연결 이 다른 WebTransport 세션과 공유될 수 있습니다.
requireUnreliable, 타입 boolean, 기본값false-
true로 설정하면, WebTransport 세션은 HTTP/3 connection이 불가능할 경우 HTTP/2 connection에서는 생성될 수 없습니다.
headers, 타입 HeadersInit, 기본값{}-
옵션으로
Headers객체, 객체 리터럴, 혹은 두 개 아이템을 가진 배열의 배열로 request의 header list를 설정. WebTransport 세션 생성 시 사용합니다. serverCertificateHashes, 타입 sequence<WebTransportHash>, 기본값[]-
이 옵션은 전용(dedicated) 연결에서만 지원됩니다. 해당 기능을 지원하지 않는 전송 프로토콜에서 이 필드 값이 비어있지 않다면,
NotSupportedError예외가 발생합니다.지원되며 비어있지 않을 경우, 사용자 에이전트는 서버 인증서가 인증서 해시 검증에 성공해야 신뢰해야 합니다.
serverCertificateHashes와 사용자 인증서 요구사항을 모두 만족해야 합니다. 사용자 에이전트는 알려지지 않은algorithm해시를 무시해야 합니다. 비어있으면, 일반 fetch 작업에서 사용하는 인증서 검증 절차를 사용합니다.이 옵션은
allowPooling과 함께 사용할 수 없습니다. congestionControl, 타입 WebTransportCongestionControl, 기본값"default"-
옵션으로 애플리케이션에서 처리량이나 저지연에 맞는 혼잡 제어 알고리즘 사용 희망을 지정할 수 있습니다. 이는 사용자 에이전트에 대한 힌트일 뿐입니다.
anticipatedConcurrentIncomingUnidirectionalStreams, 타입 unsigned short, nullable, 기본값null-
옵션으로 애플리케이션이 동시에 서버로부터 생성될 것으로 예상하는 단방향 수신 스트림 수를 지정할 수 있습니다. 사용자 에이전트는 서버에서 최소 100개의 단방향 수신 스트림 생성을 허용해야 합니다. null이 아니면, 사용자 에이전트는 서버 협상에서 라운드 트립 감소를 시도해야 합니다.
[[AnticipatedConcurrentIncomingUnidirectionalStreams]]값을 고려해서. anticipatedConcurrentIncomingBidirectionalStreams, 타입 unsigned short, nullable, 기본값null-
옵션으로 애플리케이션이 동시에 서버로부터 생성될 것으로 예상하는 양방향 스트림 수를 지정할 수 있습니다. 사용자 에이전트는 서버에서 최소 100개의 양방향 스트림 생성을 허용해야 합니다. null이 아니면, 사용자 에이전트는 서버 협상에서 라운드 트립 감소를 시도해야 하며,
[[AnticipatedConcurrentIncomingBidirectionalStreams]]값을 고려해야 합니다. protocols, 타입 sequence<DOMString>, 기본값[]-
애플리케이션 레벨의 프로토콜 이름 배열을 옵션으로 제공할 수 있습니다. 서버가 원하는 프로토콜을 선택 및 클라이언트에 전달할 수 있습니다(선택사항). 제공된 프로토콜이 적합하지 않을 경우 서버가 요청을 거부할 수도 있습니다.
datagramsReadableType, 타입 ReadableStreamType-
옵션으로, 애플리케이션이 수신 datagram에 대해 readable byte stream을 사용하고 싶으면 지정할 수 있습니다. 그 외에는 기본 readable stream이 사용됩니다.
참고: readable stream 은 datagram 의미론과 호환되지만, readable byte stream 은 그렇지 않습니다. datagram은 0 바이트 이상 메시지(순서 보장 없음)가 각각 도착할 수 있으며, 비순서화된 바이트 시퀀스가 아닙니다. 빈 datagram은 손실되고,
min을 쓰면 메시지 구분이 사라집니다.
compute a certificate hash를 수행하기 위해, certificate가 주어졌을 때 다음 단계를 수행한다:
-
cert를 certificate로 두되, [RFC5280]에 정의된 Certificate 메시지의 DER 인코딩으로 표현한다.
-
cert의 SHA-256 해시를 계산하고 계산된 값을 반환한다.
verify a certificate hash를 수행하기 위해, certificate chain과 해시 배열 hashes가 주어졌을 때, 다음 단계를 수행한다:
-
certificate를 certificate chain의 첫 번째 인증서(리프 인증서)로 둔다.
-
referenceHash를 computing a certificate hash를 certificate로 수행한 결과로 둔다.
-
hashes의 각 해시 hash에 대해:
-
hash.
value가 null이 아니고 hash.algorithm이 "sha-256"과 ASCII 대소문자 구분 없는 일치이면:-
hashValue를 hash.
value가 나타내는 바이트 시퀀스로 둔다. -
hashValue가 referenceHash와 같으면 true를 반환한다.
-
-
-
false를 반환한다.
custom certificate requirements는 다음과 같다: 인증서는 [RFC5280]에 정의된 X.509v3 인증서여야 하며, Subject Public Key 필드에서 사용되는 키는 allowed public key algorithms 중 하나여야 하고, 현재 시간은 [RFC5280]의 섹션 4.1.2.5에 정의된 인증서의 유효 기간 내에 있어야 하며 유효 기간의 총 길이는 2주를 초과해서는 안 된다. 사용자 에이전트는 인증서에 대해 추가적인 implementation-defined 요구사항을 부과할 수 있다.
Subject Public Key Info 필드(그리고 그 결과로 TLS CertificateVerify 메시지)에서 사용되는 allowed public key algorithms의 정확한 목록은 implementation-defined이다. 그러나 상호 운용 가능한 기본값을 제공하기 위해 secp256r1 (NIST P-256) named group([RFC3279], Section 2.3.5; [RFC8422])을 사용하는 ECDSA를 포함해야 한다. 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는 createUnidirectionalStream,
createBidirectionalStream,
createWritable
메서드의 동작을 제어하는 기본 매개변수 딕셔너리입니다.
dictionary WebTransportSendOptions {WebTransportSendGroup ?sendGroup =null ;long long sendOrder = 0; };
이 딕셔너리는 다음 속성을 가집니다:
sendGroup, 타입 WebTransportSendGroup, nullable, 기본값null-
생성된 스트림을 그룹(group)으로 묶기 위한 선택적
WebTransportSendGroup또는 null입니다. sendOrder, 타입 long long, 기본값0-
send order 번호를 지정하면 생성된 스트림이 엄격한 순서(strict ordering)에 참여합니다. 현재 엄격 순서(strictly ordered) 스트림에 대기 중인 바이트는 send order 번호가 더 낮은 엄격 순서(strictly ordered) 스트림에 대기 중인 바이트보다 먼저 전송됩니다.
send order 번호를 지정하지 않으면, 해당 스트림에서 바이트를 다른 스트림에 비해 언제 전송할지는 구현 정의입니다. 하지만, 사용자 에이전트는 send order 번호가 낮은 스트림에 bandwidth가 부족하지 않은 한 모든 스트림 간에 대역폭을 공평하게 분배하는 것이 권장됩니다.
참고: 이는 송신 측 데이터 우선순위화로, 수신 순서를 보장하지 않습니다.
6.12. WebTransportSendStreamOptions 딕셔너리
WebTransportSendStreamOptions는 WebTransportSendStream이
createUnidirectionalStream
또는
createBidirectionalStream
에 의해 생성될 때의 동작을 제어하는 매개변수 딕셔너리입니다.
dictionary WebTransportSendStreamOptions :WebTransportSendOptions {boolean waitUntilAvailable =false ; };
이 딕셔너리는 다음 속성을 가집니다:
waitUntilAvailable, 타입 boolean, 기본값false-
true일 때,
createUnidirectionalStream또는createBidirectionalStream호출의 프로미스는 이행(settled)되지 않습니다. 기저 연결에 스트림을 생성할 충분한 플로우 컨트롤 크레딧이 생기거나, 연결에서 더 이상 송신 스트림을 생성할 수 없는 상태가 될 때까지 대기합니다. false일 때는, 호출 시 플로우 컨트롤 윈도우가 없다면 프로미스가 reject됩니다.
6.13.
WebTransportConnectionStats 딕셔너리
WebTransportConnectionStats 딕셔너리는
WebTransport 세션의 하위 연결과 관련된
WebTransport 특화 통계 정보를 포함합니다.
참고: pooling이 사용되는 경우, 동일 WebTransport 세션이 같은 connection에 pool될 때 모든 세션이 동일 정보를 받습니다, 즉, 같은 세션이 network partition key를 공유할 때 정보가 공개됩니다.
참고: 사용 불가능한 통계 정보는
존재하지 않음
상태로
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보다 작지만, 패킷 손실로 인해 영구적으로 더 적을 수도 있습니다. 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(round-trip time) 값입니다.
rttVariation, 타입 DOMHighResTimeStamp-
[RFC9002] Section 5.3에 정의된 연결에서 관찰된 RTT 샘플의 평균 변동값입니다.
minRtt, 타입 DOMHighResTimeStamp-
[RFC9002] Section 5.2에 정의된 전체 연결에서 관찰된 최소 RTT(round-trip time) 값입니다.
estimatedSendRate, 타입 unsigned long long, nullable, 기본값null-
사용자 에이전트가 큐에 있는 데이터를 초당 비트 단위로 전송할 것으로 추정되는 속도입니다. 이 속도는 동일 WebTransport 세션 을 공유하는 모든 스트림 및 datagram에 적용됩니다. 혼잡 제어 알고리즘(예:
congestionControl로 선택 가능)이 계산합니다. 이 추정값은 프레이밍 오버헤드는 제외하며 애플리케이션 페이로드 전송 속도를 나타냅니다. 에이전트에 현 시점에서 추정값이 없으면null이어야 합니다. 이전 결과에서null이 아니었더라도null일 수 있습니다. atSendCapacity, 타입 boolean, 기본값false-
false이면
estimatedSendRate값이 애플리케이션 제한(application limited)을 의미할 수 있습니다, 즉 애플리케이션이 혼잡 제어기가 허용하는 것보다 훨씬 적은 데이터를 보냄을 뜻합니다. 혼잡 제어기가 애플리케이션 제한 상황에서 네트워크 용량을 부정확하게 추정할 수도 있습니다.true이면 애플리케이션이 네트워크 최대 용량으로 데이터를 보내고 있고,
estimatedSendRate가 애플리케이션이 사용할 수 있는 네트워크 용량을 반영합니다.atSendCapacity이true일 때estimatedSendRate값은 ceiling(최대치)를 의미합니다. 애플리케이션 전송 속도가 지속되는 한estimatedSendRate가 네트워크 상태에 맞게 적응합니다. 단,estimatedSendRate는null일 수도 있음,atSendCapacity값이 true여도 마찬가지입니다.
6.14.
WebTransportDatagramStats 딕셔너리
WebTransportDatagramStats 사전은
underlying
connection을 통한 데이터그램 전송 통계를 포함한다.
dictionary WebTransportDatagramStats {unsigned long long droppedIncoming ;unsigned long long expiredIncoming ;unsigned long long expiredOutgoing ;unsigned long long lostOutgoing ; };
이 사전에는 다음 속성이 포함되어야 한다:
droppedIncoming, 타입 unsigned long long-
애플리케이션이
datagrams의readable에서 새 데이터그램이 수신 큐를 초과하기 전에 읽지 않아 드롭된 수신 데이터그램 수 expiredIncoming, 타입 unsigned long long-
incomingMaxAge보다 오래되어datagrams의readable에서 읽히기 전에 드롭된 수신 데이터그램 수 expiredOutgoing, 타입 unsigned long long-
전송 대기 중
outgoingMaxAge보다 오래되어 전송되기 전에 드롭된 데이터그램 수 lostOutgoing, 타입 unsigned long long-
전송된 데이터그램 중 [RFC9002] Section 6.1에 정의된 대로 손실로 선언된 데이터그램 수
7. 인터페이스 WebTransportSendStream
WebTransportSendStream
은 WritableStream
으로, 송신 단방향 또는 양방향
WebTransport 스트림을 통해 데이터를 스트리밍할 수 있는 기능을 제공합니다.
이 객체는 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의
WritableStream의
단계와 동일합니다.
7.1. 속성
sendGroup, 타입 WebTransportSendGroup, 널 허용-
getter 단계:
-
this.
[[SendGroup]]값을 반환합니다.
setter 단계(value 주어질 때):
-
value가 null이 아니고 value.
[[Transport]]값이 this.[[Transport]]값이 아니라면, throwInvalidStateError를 발생시킵니다. -
this.
[[SendGroup]]를 value로 설정합니다.
-
sendOrder, 타입 long long-
getter 단계:
-
this.
[[SendOrder]]값을 반환합니다.
setter 단계(value 주어질 때):
-
this.
[[SendOrder]]값을 value로 설정합니다.
-
7.2. 메서드
getStats()-
이
WebTransportSendStream의 성능에 대한 통계를 수집하여 비동기적으로 보고한다.getStats가 호출되면, 유저 에이전트는 다음 단계들을 수행해야 한다:
-
p를 새로운 promise로 둔다.
-
아래 단계들을 병렬로 실행한다:
-
gatheredStats를 목록(list)으로, 이 this
WebTransportSendStream에 특화된 통계를WebTransportSendStreamStats의 딕셔너리 멤버들을 정확히 채울 수 있게 수집한다. -
네트워크 작업을 큐잉하여 transport에 다음을 실행한다:
-
stats를 새로운
WebTransportSendStreamStats객체로 둔다. -
유저 에이전트가 노출하려는 stats의 멤버 member마다, 해당 member를 gatheredStats의 관련 엔트리(entry)로 설정한다.
-
Promise를 resolve하여 p에 stats를 넘긴다.
-
-
-
p를 반환한다.
-
getWriter()-
이 스트림에 대한
WebTransportWriter를 생성한다.getWriter가 호출되면, WebTransportWriter 생성 결과를 this와 함께 반환한다.
7.3. 내부 슬롯
WebTransportSendStream
객체는 다음과 같은 내부 슬롯을 가진다.
| 내부 슬롯 | 설명 (비규범적) |
|---|---|
[[InternalStream]]
| 송신 단방향 또는 양방향 WebTransport 스트림. |
[[PendingOperation]]
| 대기 중인 write 또는 close 연산을 나타내는 promise, 또는 null. |
[[Transport]]
| 이 WebTransport를
소유하는 WebTransportSendStream.
|
[[SendGroup]]
| 옵션의 WebTransportSendGroup,
또는 null.
|
[[SendOrder]]
| 옵션의 송신 순서 번호, 기본값은 0. |
[[AtomicWriteRequests]]
| 정렬된 집합(ordered set)의 promise 들로, 내부 sink에서 처리 대기 중인 atomic write 요청 서브셋을 추적한다. |
[[InsideSynchronousAtomicWrite]]
| atomicWrite
메서드의 동기적 부분에서만 true인 불리언.
|
[[BytesWritten]]
| 이 스트림에 기록된 바이트 수. |
[[CommittedOffset]]
| 스트림에서, 송신 중단(aborted sending) 상태여도 피어에 전달될 바이트 수를 기록하는 오프셋; [RELIABLE-RESET] 참고. |
7.4. 절차
생성하려면,
WebTransportSendStream을
단방향 송신 또는
양방향
WebTransport 스트림
internalStream,
WebTransport
transport, sendGroup,
sendOrder를 받으면 아래 단계를 수행한다:
-
stream을 새로운
WebTransportSendStream으로 생성하며 설정값은 다음과 같다:[[InternalStream]]-
internalStream
[[PendingOperation]]-
null
[[Transport]]-
transport
[[SendGroup]]-
sendGroup
[[SendOrder]]-
sendOrder
[[AtomicWriteRequests]]-
비어있는 정렬된 집합 promise
[[InsideSynchronousAtomicWrite]]-
false
[[BytesWritten]]-
0
[[CommittedOffset]]-
0
-
writeAlgorithm을 쓰기 동작으로 설정, chunk를 stream에 쓴다.
-
closeAlgorithm을 닫기 동작으로 설정, stream을 닫는다.
-
abortAlgorithm을 중단 동작으로 설정, reason을 받아 stream을 중단한다.
-
설정을 stream에 적용, writeAlgorithm은 writeAlgorithm, closeAlgorithm은 closeAlgorithm, abortAlgorithm은 abortAlgorithm로 설정한다.
-
abortSignal을 stream의 [[controller]].[[abortController]].[[signal]]로 설정한다.
-
Add를 abortSignal에 아래 단계로 추가한다.
-
pendingOperation을 stream.
[[PendingOperation]]값으로 설정한다. -
pendingOperation이 null이면 단계 중단.
-
stream.
[[PendingOperation]]값을 null로 설정. -
reason을 abortSignal의 중단 사유 값으로 설정.
-
promise를 stream 중단 동작의 결과로 설정, reason을 인자로 전달.
-
약속 이행 시 promise가 완료되면, reject pendingOperation을 reason으로 거절한다.
-
-
Append를 stream에 대해 수행하여 transport.
[[SendStreams]]에 추가한다. -
stream을 반환한다.
WebTransportSendStream
stream에 쓰려면 아래 단계 수행:
-
transport를 stream.
[[Transport]]로 둔다. -
chunk가
BufferSource가 아니면, 거부된 promise와 함께TypeError를 반환한다. -
promise를 새로운 promise로 둔다.
-
bytes를 바이트 시퀀스에서 chunk가 나타내는 복사본으로 둔다.
-
bytes의 길이가 0이면, resolve promise하고 undefined를 넘기며 promise를 반환한다.
-
stream.
[[PendingOperation]]을 promise로 설정한다. -
inFlightWriteRequest를 stream.inFlightWriteRequest로 둔다.
-
atomic을 다음 조건에서 true로 한다: stream.
[[AtomicWriteRequests]]가 inFlightWriteRequest를 포함하거나 stream.[[InsideSynchronousAtomicWrite]]가 true. 그렇지 않으면 false. -
아래 단계를 병렬로 실행한다:
-
atomic이 true이고, 현재 흐름 제어(flow control) 윈도우가 bytes 전체를 전송하기에 부족하면, 나머지 단계를 중단하고 네트워크 작업을 큐잉하여 transport에서 다음 하위 단계를 실행:
-
stream.
[[PendingOperation]]을 null로 설정한다. -
Abort all atomic write requests를 stream에 실행한다.
-
-
그 외에는, send bytes를 stream.
[[InternalStream]]에 전송하고 operation이 완료될 때까지 기다린다. 이 전송은 송신 순서 규칙(send-order rules)을 따라야 한다.유저 에이전트는 전송 성능 향상을 위해 버퍼를 둘 수 있다. 이런 버퍼는 상한이 정해져 있어야 하며,
WebTransportSendStream의 사용자가 backpressure(역압)를 얻을 수 있도록 한다.여기서 stream.
[[SendOrder]]를 병렬로 접근한다. 유저 에이전트는 송신 중 이러한 값의 실시간 업데이트에 응답해야 한다(SHOULD). 세부 동작은 구현 정의(implementation-defined)이다.Note: 재전송의 순서는 구현 정의(implementation-defined)이지만, 유저 에이전트는
[[SendOrder]]값이 더 큰 데이터의 재전송을 우선하려고 권장됨.이 송신은 흐름 제어 또는 에러가 아닌 경우 starvation이 일어나면 안 된다(MUST NOT starve).
유저 에이전트는 starvation되지 않은 모든 스트림에 대해 bandwidth를 공정하게 배분해야 한다(SHOULD).
Note: 여기서 말하는 공정성(fairness)의 정의는 구현 정의이다.
-
이전 단계가 네트워크 오류로 실패하면, 남은 단계를 중단한다.
Note: 여기서 promise를 reject하지 않는 이유는 네트워크 오류 처리를 별도 단계에서 수행하여, 그 단계에서 stream.
[[PendingOperation]]를 reject하기 때문이다. -
그 외에는, 네트워크 작업을 큐잉하여 transport에 다음 단계 실행:
-
stream.
[[PendingOperation]]을 null로 설정한다. -
bytes의 길이를 stream.
[[BytesWritten]]에 더한다. -
stream.
[[AtomicWriteRequests]]가 inFlightWriteRequest를 포함하면, inFlightWriteRequest를 제거한다. -
Promise를 resolve하여 promise에 undefined를 넘긴다.
-
-
-
promise를 반환한다.
Note: 이 알고리즘에서 반환되는 promise(또는,
write(chunk))
의 fulfill은 반드시 청크가
서버에서 ack되었음을 의미하지 않는다.
실제로는 청크가 버퍼에 추가되었음을 의미할 수 있다.
청크가 서버에 도달했는지 확실히 하려면,
서버는 애플리케이션 수준의 ack 메시지를 보내야 한다.
WebTransportSendStream
stream을 닫으려면, 다음 단계를 수행한다:
-
transport에 stream.
[[Transport]]를 할당한다. -
promise에 새로운 promise를 할당한다.
-
stream을 transport.
[[SendStreams]]에서 제거한다. -
stream.
[[PendingOperation]]에 promise를 할당한다. -
다음 단계를 병렬로 실행한다:
-
Send FIN을 stream.
[[InternalStream]]에 전송하고, 완료될 때까지 기다린다. -
stream.
[[InternalStream]]이 "all data committed" 상태가 될 때까지 기다린다. [QUIC] -
네트워크 작업 큐에서 transport에 대해 아래 단계를 수행한다:
-
stream.
[[PendingOperation]]을 null로 설정한다. -
Resolve promise를 undefined로 완료한다.
-
-
-
promise를 반환한다.
WebTransportSendStream
stream을(를) reason과 함께 중단하려면, 다음 단계를 수행한다:
-
transport에 stream.
[[Transport]]를 할당한다. -
promise에 새로운 promise를 할당한다.
-
code에 0을 할당한다.
-
stream을 transport.
[[SendStreams]]에서 제거한다. -
reason이
WebTransportError이고, reason.[[StreamErrorCode]]가 null이 아니면, code에 reason.[[StreamErrorCode]]값을 할당한다. -
code < 0이면, code에 0을 할당한다.
-
code가 4294967295를 초과하면, code에 4294967295를 할당한다.
-
committedOffset에 stream.
[[CommittedOffset]]을 할당한다.Note: code의 유효 범위는 0~4294967295이다. 기본 연결 이 HTTP/3을 사용하는 경우, 이 코드는 [WEB-TRANSPORT-HTTP3] 에서 정의한 [0x52e4a40fa8db, 0x52e5ac983162] 범위로 인코딩된다.
-
다음 단계를 병렬로 실행한다:
-
중단을 stream.
[[InternalStream]]에 code와 committedOffset을 인자로 호출한다. -
네트워크 작업 큐에서 transport로 promise를 undefined로 해결한다.
-
-
promise를 반환한다.
WebTransportSendStream
stream에 대해 실행하려면 다음 단계를 수행:
-
writeRequests를 stream.writeRequests로 한다.
-
requestsToAbort를 stream.
[[AtomicWriteRequests]]로 둔다. -
writeRequests가 requestsToAbort에 없는 promise를 포함하고 있다면, stream에
AbortError에러를 발생시키고, 이 단계를 중단한다. -
requestsToAbort의 각 promise마다, promise를
AbortError로 reject 한다. -
병렬로, requestsToAbort의 각 promise마다, 해당 promise와 연관된 바이트의 전송(sending)을 중단한다.
7.5. 서버로부터 수신 중단 신호 받기
WebTransportSendStream
stream과 연관되어 있고,
서버로부터 receiving aborted 신호를
받으면, 다음 단계를 실행한다:
-
transport를 stream.
[[Transport]]로 한다. -
code를 receiving aborted 신호에 부착된 애플리케이션 프로토콜 오류 코드로 한다.
Note: code의 유효 값 범위는 0~4294967295까지이다. underlying connection이 HTTP/3을 사용 중이면, 이 코드는 [WEB-TRANSPORT-HTTP3]에 따라 [0x52e4a40fa8db, 0x52e5ac983162] 범위의 값으로 인코딩된다.
-
네트워크 작업을 큐잉하여 transport에서 다음을 실행한다:
-
transport.
[[State]]가"closed"또는"failed"이면 이 단계들을 중단한다. -
Remove stream을 transport.
[[SendStreams]]에서 제거한다. -
error를 새로 생성된 Exception
WebTransportError로 두며,source는"stream",streamErrorCode는 code 로 한다. -
stream.
[[PendingOperation]]이 null이 아니면 stream.[[PendingOperation]]를 error로 reject 한다. -
Error stream에 error를 발생시킨다.
-
7.6. WebTransportSendStreamStats 사전
WebTransportSendStreamStats 사전은
하나의 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 메커니즘에 의해 서버가 수신 확인을 한(acknowledged) 순차 바이트 수. 첫 번째 미acknowledged 바이트 전까지의 모든 바이트만 포함. 이 숫자는 증가만 하며bytesSent이하이다.Note: 연결이 HTTP/2일 때는 이 값이
bytesSent과 일치한다.
8. 인터페이스 WebTransportSendGroup
WebTransportSendGroup
은 여러 개의 개별
(일반적으로 엄격하게
순서화된)
WebTransportSendStream에
걸쳐 분산된 데이터 전송을 추적하는 선택적 조직 객체입니다.
WebTransportSendStream와
WebTransportDatagramsWritable는
생성 시점이나 sendGroup 속성 할당을 통해, 언제든지 최대 하나의 WebTransportSendGroup
또는 null sendGroup에 그룹될 수 있습니다.
기본적으로 WebTransportSendStream와
WebTransportDatagramsWritable는
null sendGroup에 할당됩니다.
사용자 에이전트는 WebTransportSendGroup를
WebTransportSendStream
전송 대역폭 할당 시
동등하게 취급합니다.
각 WebTransportSendGroup는
sendOrder
번호의 평가를 위한
별도의 숫자 공간(numberspace)을 설정합니다.
[Exposed =(Window ,Worker ),SecureContext ]interface {WebTransportSendGroup Promise <WebTransportSendStreamStats >getStats (); };
WebTransportSendGroup
은 항상
create 절차에 의해 생성됩니다.
8.1. 메서드
getStats()-
이
WebTransportSendStream들을 grouped 한 sendGroup 아래에서 집계된 통계를 모아 비동기적으로 보고한다.getStats가 호출되면, 유저 에이전트는 다음 절차를 따라야 한다:
-
p를 새로운 promise로 한다.
-
streams를 모든
WebTransportSendStream중[[SendGroup]]이 this인 것들로 모은다. -
아래 단계들을 병렬로 실행한다:
-
gatheredStats를, streams 내 모든 스트림의 집계된 통계로 WebTransportSendStreamStats 사전 멤버를 정확히 채우는 데 필요한 목록(list)으로 한다.
-
네트워크 작업을 큐잉하여 transport에서 아래 단계를 실행:
-
stats를 새로운
WebTransportSendStreamStats객체로 정의한다. -
유저 에이전트가 노출하려는 stats의 각 멤버(member) member에 대해서, 해당 member 값을 gatheredStats의 해당 엔트리(entry)로 설정한다.
-
promise를 resolve하여 p에 stats를 넘긴다.
-
-
-
p를 반환한다.
-
8.2. 내부 슬롯
WebTransportSendGroup
객체는 다음과 같은 내부 슬롯을 가진다.
| 내부 슬롯 | 설명 (비규범적) |
|---|---|
[[Transport]]
| 이 WebTransport
객체가 소유하고 있는 WebTransportSendGroup.
|
8.3. 절차
생성을 하려면,
WebTransportSendGroup을
WebTransport
transport와 함께, 다음 단계를 실행한다:
-
sendGroup을 new
WebTransportSendGroup으로, 다음과 같이 생성한다:[[Transport]]-
transport
-
sendGroup을 반환한다.
9. 인터페이스 WebTransportReceiveStream
WebTransportReceiveStream
은 ReadableStream
으로, 수신 단방향 또는 양방향
WebTransport 스트림을 통해 서버로부터 데이터를 스트리밍 받을 수 있는 기능을 제공합니다.
이 객체는 ReadableStream
타입의 Uint8Array
데이터로, 서버에서 수신한 데이터를 읽어서 소비할 수 있습니다. WebTransportReceiveStream
은 readable byte stream이기 때문에
소비자는 BYOB reader와 기본 리더(default
reader) 모두 사용할 수 있습니다.
[Exposed =(Window ,Worker ),SecureContext ,Transferable ]interface :WebTransportReceiveStream ReadableStream {Promise <WebTransportReceiveStreamStats >getStats (); };
WebTransportReceiveStream
은 항상
create 절차에 의해 생성됩니다.
WebTransportReceiveStream의
전송 단계 및
전송-수신 단계는
ReadableStream의 단계와 동일합니다.
9.1. 메서드
getStats()-
이
WebTransportReceiveStream의 성능에 대한 통계를 수집하여 비동기적으로 보고한다.getStats가 호출되면, 유저 에이전트는 다음 단계들을 수행해야 한다:
-
p를 새로운 promise로 둔다.
-
아래 단계들을 병렬로 실행한다:
-
gatheredStats를 목록(list)으로, 이 this
WebTransportReceiveStream에 특화된 통계를WebTransportReceiveStreamStats의 딕셔너리 멤버들을 정확히 채울 수 있게 수집한다. -
네트워크 작업을 큐잉하여 transport에서 다음 단계를 실행한다:
-
stats를 새로운
WebTransportReceiveStreamStats객체로 둔다. -
유저 에이전트가 노출하려는 stats의 멤버 member마다, 해당 member를 gatheredStats의 관련 엔트리(entry)로 설정한다.
-
Promise를 resolve하여 p에 stats를 넘긴다.
-
-
-
p를 반환한다.
-
9.2. 내부 슬롯
WebTransportReceiveStream
객체는 다음과 같은 내부 슬롯을 가지고 있습니다.
| 내부 슬롯 | 설명 (비규범적) |
|---|---|
[[InternalStream]]
| 수신 단방향 또는 양방향 WebTransport 스트림. |
[[Transport]]
| 이 WebTransport
객체가 소유한 WebTransportReceiveStream.
|
9.3. 절차
WebTransportReceiveStream
WebTransportReceiveStream
을(를)
수신 단방향 또는 양방향 WebTransport
스트림
internalStream과 WebTransport
transport와 함께 생성하려면, 다음 단계를 실행한다:
-
stream을 새로운
WebTransportReceiveStream으로, 아래와 같이 생성한다:[[InternalStream]]-
internalStream
[[Transport]]-
transport
-
pullAlgorithm을 바이트를 pull하는 동작(액션)으로 설정한다.
-
cancelAlgorithm을 cancel을 stream과 reason으로 호출하는 동작(액션)으로 설정한다.
-
바이트 읽기 지원으로 set up stream에 pullAlgorithm 을 pullAlgorithm으로 지정하고, cancelAlgorithm 을 cancelAlgorithm으로 설정한다.
-
Append stream을 transport.
[[ReceiveStreams]]에 추가한다. -
stream을 반환한다.
WebTransportReceiveStream
WebTransportReceiveStream
stream에서 바이트를 pull하려면, 다음 단계를 실행한다.
-
transport를 stream.
[[Transport]]로 한다. -
internalStream을 stream.
[[InternalStream]]로 한다. -
promise를 새로운 promise로 설정한다.
-
buffer, offset, maxBytes를 null로 한다.
-
stream의 current BYOB request view가 null이 아니라면:
-
offset을 stream의 current BYOB request view.[[ByteOffset]]로 한다.
-
maxBytes를 stream의 current BYOB request view의 바이트 길이로 한다.
-
buffer를 stream의 current BYOB request view의 underlying buffer로 설정한다.
-
-
그 외에는:
-
offset을 0으로 한다.
-
maxBytes를 구현 정의(implementation-defined) 크기로 한다.
-
buffer를 새로운
ArrayBuffer로 하고, 크기는 maxBytes로 한다. 만약ArrayBuffer할당에 실패하면, 거부된 promise와 함께RangeError를 반환한다.
-
-
아래 단계를 병렬로 실행한다:
-
Write로 read된 바이트를 internalStream에서 buffer(offset offset 위치)에 최대 maxBytes만큼 쓴다. 최소 1 바이트라도 읽거나 FIN을 받기 전까지 대기한다. read는 읽힌 바이트 수, hasReceivedFIN은 FIN을 받았는지의 여부로 설정한다.
유저 에이전트는 성능향상을 위해 내부 버퍼를 둘 수 있다. 이 버퍼는 상한이 정해져 있어야 하며, 서버에 backpressure 정보를 전달할 수 있어야 한다.
Note: 이 동작은 buffer 전체를 다 채우지 않고 반환될 수 있다.
-
이전 단계가 실패하면 나머지 단계를 중단한다.
Note: 여기서 promise를 reject하지 않는 이유는 네트워크 오류 처리를 별도 단계에서 수행하고, 그 단계에서 stream에 에러를 발생시키므로, pull을 기다리는 read 요청이 자동으로 reject된다.
-
네트워크 작업을 큐잉하여 transport에 다음 단계 실행:
Note: 위의 버퍼가 이 프로시저가 실행 중인 event loop 내부에 있다면, 이후 단계는 즉시 실행될 수 있다.
-
read > 0이면:
-
view를
Uint8Array로 새로 생성하며, 인자로 buffer, offset, read를 넘긴다. -
Enqueue view 를 stream에 넣는다.
-
-
hasReceivedFIN이 true라면:
-
stream을 transport.
[[ReceiveStreams]]에서 제거한다. -
Close stream을 호출한다.
-
-
Promise를 resolve하여 promise에 undefined를 넘긴다.
-
-
-
promise를 반환한다.
cancel
WebTransportReceiveStream
stream을 reason과 함께 취소하려면, 아래
단계를 실행한다.
-
transport를 stream.
[[Transport]]로 한다. -
internalStream을 stream.
[[InternalStream]]로 한다. -
promise를 새로운 promise로 둔다.
-
code를 0으로 한다.
-
reason이
WebTransportError이고, reason.[[StreamErrorCode]]가 null이 아니면, code를 reason.[[StreamErrorCode]]로 한다. -
code가 0보다 작으면 0으로 설정한다.
-
code가 4294967295보다 크면 4294967295로 설정한다.
Note: code의 유효 값 범위는 0~4294967295까지이다. underlying connection이 HTTP/3을 사용 중이면, 이 코드는 [WEB-TRANSPORT-HTTP3]에 따라 [0x52e4a40fa8db, 0x52e5ac983162] 범위의 값으로 인코딩된다.
-
stream을 transport.
[[SendStreams]]에서 제거한다. -
아래 단계를 병렬로 실행한다:
-
abort receiving을 internalStream에 code와 함께 호출한다.
-
네트워크 작업을 큐잉하여 transport에 다음 단계 실행:
Note: 위 버퍼가 이 프로시저가 실행 중인 event loop에 있다면, 이하 단계가 즉시 실행될 수 있다.
-
stream을 transport.
[[ReceiveStreams]]에서 제거한다. -
Promise를 resolve하여 promise에 undefined를 넘긴다.
-
-
-
promise를 반환한다.
9.4. 서버로부터 송신 중단 신호 받기
WebTransportReceiveStream
stream과 연관되어 있고,
서버로부터 sending aborted 신호를 받으면
다음 단계를 실행한다:
-
transport를 stream.
[[Transport]]로 한다. -
code를 sending aborted 신호에 부착된 애플리케이션 프로토콜 오류 코드로 한다.
Note: code의 유효 값 범위는 0~4294967295이다. underlying connection이 HTTP/3을 사용 중이면, 이 코드는 [0x52e4a40fa8db, 0x52e5ac983162] 범위의 값으로 인코딩된다. (자세한 내용은 [WEB-TRANSPORT-HTTP3] 참고)
-
네트워크 작업을 큐잉하여 transport에 다음을 실행한다:
-
transport.
[[State]]가"closed"또는"failed"면 이 단계들을 중단한다. -
stream을 transport.
[[ReceiveStreams]]에서 제거한다. -
error를 새로 생성된 예외
WebTransportError로 두고,source는"stream",streamErrorCode는 code로 한다. -
stream에 error를 발생시킨다.
-
9.5. WebTransportReceiveStreamStats 사전
WebTransportReceiveStreamStats 사전은
하나의 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, 읽기 전용-
getter 단계는 this의
[[Readable]]를 반환하는 것이다. writable, 타입 WebTransportSendStream, 읽기 전용-
getter 단계는 this의
[[Writable]]를 반환하는 것이다.
10.3. 절차
WebTransportBidirectionalStream
을(를)
양방향(bidirectional)
WebTransport 스트림 internalStream, WebTransport
객체 transport, sendOrder와 함께 생성하려면 다음 단계를 실행한다.
-
readable을 WebTransportReceiveStream 생성 결과로 두되, 인자는 internalStream과 transport를 넘긴다.
-
writable을 WebTransportSendStream 생성 결과로 두되, 인자는 internalStream, transport, sendOrder를 넘긴다.
-
stream을 새로운
WebTransportBidirectionalStream으로 하고, 다음 슬롯들로 초기화한다:[[Readable]]-
readable
[[Writable]]-
writable
[[Transport]]-
transport
-
stream을 반환한다.
11.
WebTransportWriter 인터페이스
WebTransportWriter
는 WritableStreamDefaultWriter
의 서브클래스로,
두 개의 메서드가 추가된다.
WebTransportWriter
는 항상
생성(create)
절차에 의해 생성된다.
[Exposed=*,SecureContext ]interface :WebTransportWriter WritableStreamDefaultWriter {Promise <undefined >atomicWrite (optional any );chunk undefined commit (); };
11.1. 메서드
atomicWrite(chunk)-
atomicWrite메서드는 전달된 chunk 전체가 전송 시점의 흐름 제어 윈도우 내에서 전부 보내질 수 없으면 reject된다. 이는 흐름 제어 데드락에 민감한 틈새 트랜잭션 애플리케이션을 지원하기 위한 동작이다 ([RFC9308] Section 4.4).Note:
atomicWrite는 일부 데이터를 전송한 뒤에도 reject 될 수 있다. 흐름 제어에 대한 원자성은 보장하지만, 다른 에러는 발생할 수 있다.atomicWrite는 데이터가 패킷 사이에 분할되거나 다른 데이터와 interleave되는 것을 막지 않는다. 흐름 제어 credit 부족으로 인해atomicWrite가 실패할 경우, 그 사실을 알 수 있는 건 송신자 뿐이다.Note: atomic write 역시 non-atomic write가 대기열에 앞서 있을 경우 블록될 수 있다. atomic write가 거부되면, 그 시점에 대기열에 있는 모든 요청도 같이 reject된다. 이 방식으로 reject된 non-atomic write 는 스트림 에러를 발생시킨다. 따라서 애플리케이션에서는 atomic write를 항상 await하도록 권장된다.
atomicWrite(chunk)가 호출되면, 유저 에이전트는 다음 단계를 수행해야 한다:-
stream이 undefined이면, 거부된 promise와 함께
TypeError를 반환한다. -
stream.
[[InsideSynchronousAtomicWrite]]를 true로 설정한다. -
p를 chunk 쓰기(write) 결과로 둔다.
-
stream.
[[InsideSynchronousAtomicWrite]]를 false로 설정한다. -
Append p를 stream.
[[AtomicWriteRequests]]에 추가한다. -
promise settled reaction 으로, p에 대해 아래 단계를 실행한 결과를 반환한다:
-
stream.
[[AtomicWriteRequests]]가 p를 포함하고 있다면, 제거한다. -
p가 r을 reason으로 reject되었으면, 거부된 promise와 함께 r을 반환한다.
-
undefined를 반환한다.
-
commit()-
commit메서드는 스트림의[[CommittedOffset]]을 해당 스트림에 기록된 바이트 수([[BytesWritten]]) 로 갱신한다. 이로써 abort 이후에도 해당 바이트는 abort 되어 송신 중단된 경우에도 피어에 확실히 전달됨을 보장한다. 이 동작은 [RELIABLE-RESET]의 메커니즘을 사용한다.Note: 연결 자체가 끊어진 경우에는 전달의 보증은 되지 않으며, 스트림이 송신 중단(aborted) 되었을 때만 해당한다.
commit이 stream에 대해 호출되면, 유저 에이전트는 다음 단계를 수행한다:-
stream.
[[CommittedOffset]]을 stream.[[BytesWritten]]값으로 설정한다.
-
11.2. 절차
WebTransportWriter 생성을 하려면,
WebTransportWriter에
WebTransportSendStream
stream을 넘겨 다음 단계를 수행한다:
-
writer를 새로운
WebTransportWriter로 둔다. -
SetUpWritableStreamDefaultWriter(writer, stream)를 수행한다.
-
writer를 반환한다.
12.
WebTransportError 인터페이스
WebTransportError는 DOMException
의 하위 클래스입니다.
-
서버 또는 네트워크에서 발생한 오류, 또는
-
클라이언트에서 시작된 중단 작업의 사유.
[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 = "stream"; [source Clamp ]unsigned long ?=streamErrorCode null ; };enum {WebTransportErrorSource ,"stream" , };"session"
12.1. 내부 슬롯
WebTransportError
은 다음 내부 슬롯을 가집니다.
| 내부 슬롯 | 설명 (비규범적) |
|---|---|
[[Source]]
| WebTransportErrorSource로,
이 오류의 원인을 나타냅니다.
|
[[StreamErrorCode]]
| 이 오류에 대한 응용 프로토콜 오류 코드, 또는 null. |
12.2. 생성자
new WebTransportError(message, options)
생성자 단계는 다음과 같습니다:
-
this의 name을
"WebTransportError"로 설정합니다. -
this의 message를 message로 설정합니다.
-
this의 내부 슬롯을 아래와 같이 설정합니다:
[[Source]]-
options.
source [[StreamErrorCode]]-
options.
streamErrorCode
12.3. 속성
source, 타입 WebTransportErrorSource, 읽기 전용-
getter 단계는 this의
[[Source]]를 반환하는 것이다. streamErrorCode, 타입 unsigned long, 읽기 전용, nullable-
getter 단계는 this의
[[StreamErrorCode]]를 반환하는 것이다.
12.4. 직렬화
WebTransportError
객체는 직렬화 가능한 객체입니다.
해당 직렬화 단계(value와 serialized가 주어짐)는 다음과 같습니다:
-
DOMException직렬화 단계를 value와 serialized로 실행합니다. -
serialized.
[[Source]]에 value.[[Source]]를 설정합니다. -
serialized.
[[StreamErrorCode]]에 value.[[StreamErrorCode]]를 설정합니다.
해당 역직렬화 단계(serialized와 value가 주어짐)는 다음과 같습니다:
-
DOMException역직렬화 단계를 serialized와 value로 실행합니다. -
value.
[[Source]]를 serialized.[[Source]]로 설정합니다. -
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의 전송 중단(aborts sending), httpErrorCode와
[[CommittedOffset]]
(해당 stream
에 대한 값) 및 stream header 포함;
[RELIABLE-RESET] 참고
|
writable.close()
| FIN 비트가 설정된 STREAM 전송 |
writable.getWriter().write(chunk)()
| STREAM 전송 |
writable.getWriter().close()
| FIN 비트가 설정된 STREAM 전송 |
writable.getWriter().abort(error)
| STREAM의 전송 중단(aborts sending), httpErrorCode와
[[CommittedOffset]]
(해당 stream
에 대한 값) 및 stream header 포함;
[RELIABLE-RESET] 참고
|
readable.cancel(error)
| STREAM 수신 중단(aborts receiving), httpErrorCode와 함께 |
readable.getReader().cancel(error)
| STREAM 수신 중단(aborts receiving), httpErrorCode와 함께 |
wt.close(closeInfo)
| 세션
종료(terminate), closeInfo와 함께 |
| QUIC 프로토콜 동작 | API 효과 |
|---|---|
| httpErrorCode와 함께 STOP_SENDING 수신 | 에러(errors) writable
, streamErrorCode로
|
| STREAM 수신(received) | (await
readable.getReader().read()).value
|
| FIN 비트가 설정된 STREAM 수신 | (await
readable.getReader().read()).done
|
| httpErrorCode와 함께 RESET_STREAM 수신 | 에러(errors) readable
, streamErrorCode로
|
| 세션이 clean하게 종료(terminated), closeInfo와 함께 | (await wt.closed).closeInfo,
및
열린 스트림에 에러
|
| 네트워크 오류 | (await wt.closed)
rejected,
열린 스트림에 에러
|
참고: [QUIC] RFC9000 3.2장에서 논의된 바와 같이, RESET_STREAM 프레임이나 RESET_STREAM_AT 프레임([RELIABLE-RESET])의 수신은 항상 애플리케이션에 바로 표시되는 것은 아닙니다. 리셋 수신 신호는 즉시 전달될 수 있으며, 스트림 데이터 전달이 중단되고 소비되지 않은 데이터는 폐기될 수 있습니다. 하지만 즉시 신호 전달이 반드시 필요한 것은 아닙니다. 특히 RESET_STREAM_AT 프레임의 Reliable Size 필드에 표시된 데이터 전달을 허용하기 위해 신호가 지연될 수 있습니다. 스트림 데이터가 완전히 수신되었지만 애플리케이션에서 아직 읽지 않은 경우에는 송신 중단 신호가 생략될 수 있습니다. WebTransport는 항상 스트림 헤더의 신뢰성 전달을 보장하기 위해 RESET_STREAM_AT 프레임을 사용합니다; 자세한 내용은 HTTP/3 4.1장과 HTTP/3 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 전송 중단(aborts sending), error와 함께 |
writable.close()
| FIN 비트가 설정된 WT_STREAM 전송 |
writable.getWriter().write()
| WT_STREAM 전송 |
writable.getWriter().close()
| FIN 비트가 설정된 WT_STREAM 전송 |
writable.getWriter().abort(error)
| WT_STREAM 전송 중단(aborts sending), error와 함께 |
readable.cancel(error)
| WT_STREAM 수신 중단(aborts receiving), error와 함께 |
readable.getReader().cancel(error)
| WT_STREAM 수신 중단(aborts receiving), error와 함께 |
wt.close(closeInfo)
| 세션
종료(terminates), closeInfo와 함께 |
| HTTP/2 프로토콜 동작 | API 효과 |
|---|---|
| error와 함께 WT_STOP_SENDING 수신 | 에러(errors) writable
, streamErrorCode로
|
| WT_STREAM 수신(received) | (await
readable.getReader().read()).value
|
| FIN 비트가 설정된 WT_STREAM 수신 | (await
readable.getReader().read()).done
|
| error와 함께 WT_RESET_STREAM 수신 | 에러(errors) readable
, streamErrorCode로
|
| 세션이 clean하게 종료(terminated), closeInfo와 함께 | (await wt.closed).closeInfo,
및
열린 스트림에 에러
|
| 네트워크 오류 | (await wt.closed)
rejected,
열린 스트림에 에러
|
| 세션이 draining 시작 | await wt.draining
|
14. 프라이버시 및 보안 고려사항
이 섹션은 비규범적입니다. 새로운 동작을 지정하지 않으며, 명세의 다른 부분에 이미 존재하는 정보를 요약합니다.
14.1. 통신의 기밀성
네트워크를 관찰할 수 있는 공격자는 통신이 이루어지고 있다는 사실을 숨길 수 없습니다. 이는 공개 정보로 간주되어야 합니다.
이 문서에서 설명하는 모든 전송 프로토콜은 TLS [RFC8446] 또는 의미적으로 동등한 프로토콜을 사용하므로, TLS의 모든 보안 속성(트래픽의 기밀성 및 무결성 포함)을 제공합니다. HTTP를 통한 WebTransport는 아웃바운드 HTTP 요청과 동일한 인증서 검증 메커니즘을 사용하므로, 원격 서버 인증을 위한 동일한 공개키 인프라에 의존합니다. WebTransport에서는 인증서 검증 오류가 치명적이며, 인증서 검증을 우회할 수 있는 중간 경유(interstitial)는 제공되지 않습니다.
14.2. 상태 지속성
WebTransport는 고유 식별자나 새로운 상태 지속 방법을 자체적으로 생성하지 않으며, 기존의 지속 상태를 서버에 자동으로 노출하지도 않습니다. 예를 들어, [WEB-TRANSPORT-HTTP3]나 [WEB-TRANSPORT-HTTP2]는 쿠키를 전송하거나 HTTP 인증 또는 캐싱 무효화 메커니즘을 지원하지 않습니다. TLS를 사용하기 때문에 TLS 세션 티켓 등 TLS의 지속 상태는 상속받으며, 이는 수동적 네트워크 관찰자에게는 보이지 않지만 서버가 동일 클라이언트의 여러 연결을 연관시키는 데 사용할 수 있습니다.
14.3. 프로토콜 보안
WebTransport는 [WEB-TRANSPORT-OVERVIEW]에서 설명된 요구사항을 부과합니다. 예:
-
원격 서버가 WebTransport 프로토콜이 사용 중임을 인지하도록 하고, 원격 서버가 WebTransport 프로토콜 사용에 동의함을 확인한다. [WEB-TRANSPORT-HTTP3]는 ALPN [RFC7301], HTTP/3 설정, 그리고 WebTransport 프로토콜을 식별하기 위한
:protocolpseudo-header의 조합을 사용한다. [WEB-TRANSPORT-HTTP2]는 ALPN, HTTP/2 설정, 그리고 WebTransport 프로토콜을 식별하기 위한:protocolpseudo-header의 조합을 사용한다. -
전송 세션을 시작한 리소스의 오리진에 기반하여 서버가 연결을 필터링할 수 있도록 허용한다. 세션 설정 요청의
Origin헤더 필드가 이 정보를 담는다.
프로토콜 보안 관련 고려사항은 보안 고려사항(Security Considerations) 섹션에서 설명되어 있습니다. [WEB-TRANSPORT-OVERVIEW] 섹션 6, [WEB-TRANSPORT-HTTP3] 섹션 8, 그리고 [WEB-TRANSPORT-HTTP2] 섹션 9에서 확인할 수 있습니다.
네트워킹 API는 일반적으로 로컬 네트워크의 사용 가능한 호스트를 스캔하는 데 사용될 수 있으므로, 지문 채취(fingerprinting) 및 기타 공격에 활용될 수 있습니다. WebTransport는 WebSocket 방식을 따릅니다: 특정 연결 오류는 WebTransport 엔드포인트임이 확인될 때까지 반환되지 않습니다. 따라서 웹 애플리케이션은 존재하지 않는 엔드포인트와 Web에서 연결을 받아들이지 않는 엔드포인트를 구분할 수 없습니다.
14.4. 인증서 해시를 통한 인증
일반적으로, 유저 에이전트는 TLS 서버 인증서의 유효성을 URL의 서버 이름에 대해 검증함으로써 TLS 연결을 인증합니다 [RFC9525]. 이는 유저 에이전트가 유지하는 신뢰 앵커로 서버 인증서를 체인 연결하는 방식입니다; 신뢰 앵커는 인증서의 서버 이름을 인증합니다. 이 시스템을 Web PKI라 부릅니다.
이 API는 웹 애플리케이션이 서버 이름 대신 특정 서버 인증서로 인증된 원격 네트워크 엔드포인트에 연결할 수 있게 합니다. 이 메커니즘은 장기 인증서 취득이 어려운 엔드포인트(예: 단명 VM, 공개 라우팅이 안 되는 호스트)와의 연결을 가능하게 합니다. 이 메커니즘이 개별 연결에 대해 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는 사이트가 네트워크 활동을 생성하고, 그 효과를 세밀하게 관찰할 수 있게 합니다. 이런 방식으로 얻은 정보는 식별 정보가 될 수 있습니다.
매우 유사한 네트워킹 기능이 다른 웹 플랫폼 API(예: fetch, [webrtc])에도 있으므로, WebTransport 추가로 인한 프라이버시 악영향은 최소입니다. 이 섹션의 고려사항은 다른 네트워킹 기능에도 똑같이 적용됩니다.
네트워크 특성 측정은 네트워크를 실제로 사용하고, 그 사용의 효과를 측정해야 하며, 이 둘 모두 이 API로 가능합니다. WebTransport는 사이트가 원하는 서버로 네트워크 활동을 생성하고 효과를 관찰할 수 있게 합니다. 네트워크 경로의 안정적 속성과 동적 사용 효과 모두 관찰이 가능합니다.
네트워크 정보는 서버에 직접 네트워킹 스택을 통해, 혹은 클라이언트의 데이터 소비/전송 속도, 또는 API에서 제공하는 통계 (§ 6.13 WebTransportConnectionStats Dictionary)로 제공됩니다. 따라서 사용자 에이전트의 정보 제한만으로 프라이버시 위험을 관리할 수 없습니다.
14.5.1. 정적 관찰
사이트는 사용자 에이전트와 선택한 서버 간의 네트워크 용량 또는 왕복 시간(RTT)을 관찰할 수 있습니다. 이 정보는 다른 추적 벡터와 결합되면 식별 정보가 될 수 있습니다. RTT는 여러 측정이 여러 관찰 지점에서 이루어질 경우, 사용자 에이전트의 물리적 위치도 일부 드러낼 수 있습니다.
네트워킹은 공유되지만, 네트워크 사용은 종종 산발적이기 때문에, 사이트는 종종 경쟁이 없거나 거의 없는 네트워크 경로의 용량과 RTT를 관찰할 수 있습니다. 이러한 특성은 네트워크 위치와 병목 위치가 고정된 사용자에게는 안정적입니다.
14.5.2. 공유 네트워킹
경쟁이 있는 링크는 사이트에 사이트 간 인식을 활성화할 기회를 제공합니다. 이는 무단 추적에 활용될 수 있습니다 [UNSANCTIONED-TRACKING]. 네트워크 용량은 한정된 공유 자원이므로, 사용자 에이전트가 여러 사이트에 동시에 접근하면 각 사이트에 제시되는 신원 간의 연결이 드러날 수 있습니다.
한 사이트의 네트워킹 기능 사용은 다른 사이트에서 사용할 수 있는 용량을 감소시키며, 이는 네트워킹 API를 통해 관찰될 수 있습니다. 네트워크 사용과 지표는 동적으로 변할 수 있으므로, 모든 변화가 실시간으로 관찰 가능합니다. 이를 통해 사이트는 서로 다른 사이트의 활동이 동일 사용자에서 비롯된 것임을 더욱 확신할 수 있습니다.
사용자 에이전트는 비활성 또는 포커스가 없는 사이트에 대해 통계 (§ 6.13 WebTransportConnectionStats Dictionary)와 같은 피드백 메커니즘 접근을 제한하거나 저하시킬 수 있습니다 (HTML § 6.6 포커스). 단, 서버가 네트워크 변화 관찰을 막을 수는 없습니다.
14.5.3. 풀링된 세션
공유 네트워킹 시나리오와 유사하게, 여러 세션이 하나의 연결에 풀링될 때, 한 세션의 정보가 다른 세션의 활동에 의해 영향을 받습니다. 한 세션은 다른 세션의 데이터 전송 속도 등 활동 정보를 추론할 수 있습니다.
공유 연결 사용만으로도 서버가 세션을 연관지을 수 있습니다. 네트워크 파티션 키를 사용하면, 공유 세션으로 인해 원치 않는 사이트 간 인식이 활성화되는 것을 방지할 수 있습니다.
15. 예시
15.1. 데이터그램 버퍼 전송
이 섹션은 비규범적입니다.
데이터그램 버퍼 전송은
datagrams의
createWritable
메서드와, 결과 스트림의 writer를 사용하여 달성할 수 있습니다. 아래 예시에서는 트랜스포트가 전송 준비가 되었을 때만 데이터그램을 전송합니다.
async function sendDatagrams( url, datagrams) { const wt= new WebTransport( url); const writable= wt. datagrams. createWritable(); const writer= writable. getWriter(); for ( const bytesof datagrams) { await writer. ready; writer. write( bytes). catch (() => {}); } await writer. close(); }
15.2. 고정 간격으로 데이터그램 전송
이 섹션은 비규범적입니다.
트랜스포트가 전송 준비가 되었는지 여부와 상관없이 고정 간격으로 데이터그램을 전송하려면,
datagrams의
createWritable
메서드와 결과 스트림의 writer를 사용하되, ready 속성을 await하지 않으면 됩니다.
// 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 datagramof wt. datagrams. readable) { // 데이터그램 처리 } }
15.4. BYOB 리더로 데이터그램 수신
이 섹션은 비규범적입니다.
datagrams
는 읽을 수 있는 바이트 스트림이므로, BYOB(Bring Your Own Buffer
리더)를 사용할 수 있습니다. BYOB 리더를 사용하면 버퍼 할당을 더욱 정밀하게 제어할 수 있어 복사를 방지할 수 있습니다. 이 예제에서는 64 kibibytes 메모리 버퍼에
데이터그램을
읽어옵니다.
const wt= new WebTransport( url); for await ( const datagramof 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를 사용합니다.
작성된 청크 경계는 수신 시 유지되지 않을 수 있으며, 바이트가 전송 중에 합쳐질 수 있습니다. 따라서 응용에서는 자체 프레이밍을 제공하는 것이 좋습니다.
async function sendData( url, ... data) { const wt= new WebTransport( url); const writable= await wt. createUnidirectionalStream(); const writer= writable. getWriter(); for ( const bytesof data) { await writer. ready; writer. write( bytes). catch (() => {}); } await writer. close(); }
Streams 명세는 write()의 promise를 await하지 않는 것 을 권장하지 않습니다.
인코딩은 ReadableStream에서
파이프를 통해서도 할 수 있습니다.
예를 들어
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 readableof wt. incomingUnidirectionalStreams) { // 각각의 스트림을 IIFE로 소비, 스트림별 에러 보고 (( async () => { try { for await ( const bytesof readable) { processTheData( bytes); } } catch ( e) { console. error( e); } })()); } }
디코딩은 새 WritableStream으로 파이프를 통해서도 할 수 있습니다. 예를 들어
TextDecoderStream
을 사용할 수 있습니다.
이 예시는 텍스트 출력이 interleave되지 않아야 한다고 가정하여, 한 번에 하나의 스트림만 읽습니다.
async function receiveText( url, createWritableStreamForTextData) { const wt= new WebTransport( url); for await ( const readableof wt. incomingUnidirectionalStreams) { // 출력이 interleave되지 않도록 순차적으로 소비, 스트림별 에러 보고 try { await readable. pipeThrough( new TextDecoderStream( "utf-8" )) . pipeTo( createWritableStreamForTextData()); } catch ( e) { console. error( e); } } }
15.7. BYOB 리더로 스트림 수신
이 섹션은 비규범적입니다.
WebTransportReceiveStream은
읽기 가능한 바이트 스트림(readable byte streams)이므로,
BYOB
리더(reader)를 사용할 수 있습니다.
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; // 흐름 제어 블록 방지로 거절됨 // 비원자적 쓰기가 pending이 아니라면 writable은 에러 상태가 되지 않음 } finally { writer. releaseLock(); } }
15.9. 서버 인증서 해시 사용
이 섹션은 비규범적입니다.
WebTransport 세션은 클라이언트의 기본 신뢰 평가 대신,
서버에 제공된 인증서의 해시값을 검사하여 신뢰성을 평가하도록 할 수 있습니다. 아래 예시에서 hashValue는
BufferSource
타입으로,
서버 인증서의 SHA-256 해시를 담고 있으며, 기저 연결이 이를 유효로 간주해야 합니다.
const wt= new WebTransport( url, { serverCertificateHashes: [ { algorithm: "sha-256" , value: hashValue, } ] }); await wt. ready;
15.10. 전체 예시
이 섹션은 비규범적입니다.
이 예시는 closed, ready promise 활용, 클라이언트/서버의 단방향 및 양방향 스트림 열기, 데이터그램 송수신 등을 보여줍니다.
writable 속성은
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 dataof wt. datagrams. readable. pipeThrough( decoder)) { addToEventLog( `데이터그램 수신: ${ data} ` ); } addToEventLog( '데이터그램 읽기 완료!' ); } catch ( e) { addToEventLog( `데이터그램 읽기 중 오류: ${ e} ` , 'error' ); } } async function acceptUnidirectionalStreams() { try { for await ( const readableof 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 dataof 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
인터페이스는 QuicTransport 인터페이스를 기반으로 하며,
이는 W3C ORTC CG에서 처음 기술되었습니다.
이 명세서에 맞게 적용되었습니다.