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]에 정의된 다음 기능을 가집니다:
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 스트림은 단방향(수신), 단방향(송신) 또는 양방향 중 하나입니다.
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객체가 아니라면, TypeError로 거부된 프로미스를 반환합니다. -
datagrams를 transport.
[[Datagrams]]로 설정합니다. -
datagrams.
[[OutgoingMaxDatagramSize]]가 data의 [[ByteLength]]보다 작으면, undefined로 해결된 프로미스를 반환합니다. -
새 프로미스 promise를 생성합니다.
-
data가 나타내는 바이트를 복사하여 bytes로 설정합니다.
-
chunk를 bytes, timestamp, promise의 튜플로 설정합니다.
-
writable.
[[OutgoingDatagramsQueue]]에 chunk를 큐에 추가합니다. -
writable.
[[OutgoingDatagramsQueue]]의 길이가 datagrams.[[OutgoingDatagramsHighWaterMark]]보다 작으면, 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합니다.
-
-
사용자 에이전트는 WebTransport
객체 중
[[State]]가
"connecting" 또는 "connected"인 경우,
관련 WebTransportDatagramsWritable
객체의 일부(송신 순서 규칙에 따라 결정됨)에 대해 sendDatagrams를 실행해야 하며,
알고리즘이 진행 가능할 때 최대한 빨리 실행하는 것이 바람직합니다.
송신 순서 규칙은,
일반적으로 송신은 이전에 큐에 추가된 스트림 및 데이터그램, 앞으로 큐에 추가될 스트림 및 데이터그램의 송신과 교차될 수 있지만,
송신은 동일한 [[SendGroup]]
및 더 높은 [[SendOrder]]
값을 가진,
에러나 에러 상태 또는 흐름 제어로 인해 블록되지 않은 모든 바이트가
송신될 때까지 대기해야 한다는 것입니다.
참고: 트랜스포트의 [[State]]
값이 "connecting"일 때 데이터그램 작성이 허용됩니다.
데이터그램은 [[OutgoingDatagramsQueue]]에
저장되고,
"connected" 상태일 때와 동일한 방식으로 폐기될 수 있습니다. 트랜스포트의 [[State]]가
"connected"가 되면 큐에 있던 데이터그램 송신을 시작합니다.
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 unrestricted double incomingHighWaterMark ;attribute unrestricted double outgoingHighWaterMark ; };
5.1. 내부 슬롯
WebTransportDatagramDuplexStream
객체는 다음 내부 슬롯을 가집니다.
| 내부 슬롯 | 설명 (규범적이지 않음) |
|---|---|
[[Transport]]
| 이 WebTransport
를 소유하는 WebTransportDatagramDuplexStream
|
[[Readable]]
| 수신 데이터그램용 ReadableStream
|
[[ReadableType]]
| 수신 데이터그램에 사용되는 ReadableStreamType
|
[[Writables]]
|
순서가 지정된 집합의 WebTransportDatagramsWritable
스트림, 처음에는 비어 있음
|
[[IncomingDatagramsQueue]]
| 수신 데이터그램과 타임스탬프 쌍의 큐 |
[[IncomingDatagramsPullPromise]]
| pullDatagrams에 의해 설정되는 promise로, 수신 데이터그램을 대기함 |
[[IncomingDatagramsHighWaterMark]]
| unrestricted double로,
수신 데이터그램의 high water mark를 나타냄
|
[[IncomingDatagramsExpirationDuration]]
| unrestricted double
수신 데이터그램의 만료 지속 시간(밀리초)을 나타내며, null일 수 있음
|
[[OutgoingDatagramsHighWaterMark]]
| unrestricted double로,
송신 데이터그램의 high water mark를 나타냄
|
[[OutgoingDatagramsExpirationDuration]]
| unrestricted double
값으로, 송신 데이터그램의 만료 지속 시간(밀리초)을 나타내며, null일 수 있음
|
[[OutgoingMaxDatagramSize]]
|
송신 데이터그램의 최대 크기를 나타내는 정수
최대 데이터그램 크기는 사용 중인 프로토콜에 따라 다름
HTTP/3 [WEB-TRANSPORT-HTTP3]에서는 값이 경로 MTU의 추정치와 관련이 있고,
오버헤드를 고려하여 구현 정의 양만큼 감소됨.
HTTP/2 [WEB-TRANSPORT-HTTP2]에는 해당 제한이 없음
데이터그램 처리는 전체 데이터그램을 메모리에 보관하는 경우가 많으므로, 구현에는 크기 제한이 있음. 향후 프로토콜 확장에서는 모든 프로토콜 변형에 대한 이러한 크기 제한 신호화가 가능할 수 있음. |
사용자 에이전트는 [[OutgoingMaxDatagramSize]]
를 WebTransport
객체의
[[State]]
가 "connecting" 또는 "connected" 일 때 갱신할 수 있음.
WebTransportDatagramDuplexStream
을 주어진 WebTransport
transport, readable 및 readableType으로 아래 단계를 수행
-
stream을 new
WebTransportDatagramDuplexStream로 생성하고, 다음과 같음:[[Transport]]-
transport
[[Readable]]-
readable
[[ReadableType]]-
readableType
[[Writables]]-
비어 있는 순서가 지정된 집합
[[IncomingDatagramsQueue]]-
빈 큐
[[IncomingDatagramsPullPromise]]-
null
[[IncomingDatagramsHighWaterMark]]-
구현 정의 값
[[IncomingDatagramsExpirationDuration]]-
null
[[OutgoingDatagramsHighWaterMark]]-
구현 정의 값
이 구현 정의 값은 전송 데이터의 적시성이 저해되지 않는 선에서 적절한 처리량을 보장하도록 조율되어야 함.
[[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, of type ReadableStream, readonly-
getter 단계:
-
this.
[[Readable]]를 반환.
-
incomingMaxAge, of type unrestricted double, nullable-
getter 단계:
setter 단계: value가 주어지면,
-
value가 음수이거나 NaN이면, throw
RangeError. -
value가
0이면 value를 null로 설정. -
this.
[[IncomingDatagramsExpirationDuration]]를 value로 설정.
maxDatagramSize, of type unsigned long, readonly-
WebTransportDatagramsWritable에 전달할 수 있는 최대 데이터 크기. getter 단계는 this.[[OutgoingMaxDatagramSize]]를 반환. outgoingMaxAge, of type unrestricted double, nullable-
getter 단계:
setter 단계: value가 주어지면,
-
value가 음수이거나 NaN이면, throw
RangeError. -
value가
0이면 value를 null로 설정. -
this.
[[OutgoingDatagramsExpirationDuration]]를 value로 설정.
incomingHighWaterMark, of type unrestricted double-
getter 단계:
setter 단계: value가 주어지면,
-
value가 음수이거나 NaN이면, throw
RangeError. -
value가
1미만이면 value를1로 설정. -
this.
[[IncomingDatagramsHighWaterMark]]를 value로 설정.
outgoingHighWaterMark, of type unrestricted double-
getter 단계:
setter 단계: value가 주어지면,
-
value가 음수이거나 NaN이면, throw
RangeError. -
value가
1미만이면 value를1로 설정. -
this.
[[OutgoingDatagramsHighWaterMark]]를 value로 설정.
5.4. 절차
pullDatagrams를 하려면,
WebTransport
객체 transport가 주어졌을 때 다음 단계를 실행한다:
-
datagrams를 transport.
[[Datagrams]]로 한다. -
단언: datagrams.
[[IncomingDatagramsPullPromise]]는 null이다. -
queue를 datagrams.
[[IncomingDatagramsQueue]]로 한다. -
queue가 비어 있으면,
-
datagrams.
[[IncomingDatagramsPullPromise]]에 새 promise를 넣는다. -
datagrams.
[[IncomingDatagramsPullPromise]]를 반환.
-
-
datagram과 timestamp를 dequeuing queue의 결과로 한다.
-
datagrams.
[[ReadableType]]이"bytes"이면:-
datagrams.
[[Readable]]의 current BYOB request view가 null이 아니면,-
view를 datagrams.
[[Readable]]의 current BYOB request view로 한다. -
view의 byte length가 datagram의 크기보다 작으면, a promise rejected with
RangeError를 반환한다. -
elementSize를 the typed array constructors table에서 view.[[TypedArrayName]]에 해당하는 element size로 한다. view에 [[TypedArrayName]] 내부 슬롯이 없으면 (
DataView인 경우) elementSize는 0으로 한다. -
elementSize가 1이 아니면, a promise rejected with
TypeError를 반환한다.
-
-
Pull from bytes datagram을 datagrams.
[[Readable]]에 넣는다.
-
-
그 밖의 경우:
-
chunk를 datagram을 나타내는 새로운
Uint8Array객체로 한다. -
Enqueue chunk를 transport.
[[Datagrams]].[[Readable]]로 넣는다.
-
-
a promise resolved with undefined를 반환한다.
receiveDatagrams를 하려면,
WebTransport
객체 transport가 주어졌을 때 다음 단계를 실행한다:
-
timestamp를 현재 시점을 나타내는 타임스탬프로 한다.
-
queue를 datagrams.
[[IncomingDatagramsQueue]]로 한다. -
duration을 datagrams.
[[IncomingDatagramsExpirationDuration]]로 한다. -
duration이 null이면 duration을 implementation-defined 값으로 설정한다.
-
session을 transport.
[[Session]]으로 한다. -
session에 available incoming datagrams가 있을 때 반복:
-
datagram을 receiving a datagram로 session을 사용하여 구한다.
-
timestamp를 현재 시점을 나타내는 타임스탬프로 한다.
-
chunk를 datagram과 timestamp의 쌍으로 한다.
-
Enqueue chunk를 queue에 넣는다.
-
-
toBeRemoved를 queue의 길이에서 datagrams.
[[IncomingDatagramsHighWaterMark]]를 뺀 값으로 한다. -
toBeRemoved가 양수이면, dequeuing queue를 toBeRemoved (내림 처리)번 반복한다.
-
queue가 비어있지 않을 때 반복:
-
queue가 비어있지 않고 datagrams.
[[IncomingDatagramsPullPromise]]가 null이 아니면,-
bytes, timestamp를 dequeuing queue의 결과로 한다.
-
promise를 datagrams.
[[IncomingDatagramsPullPromise]]로 한다. -
datagrams.
[[IncomingDatagramsPullPromise]]를 null로 설정한다. -
Queue a network task를 transport로 다음 단계를 실행하게 한다:
-
chunk를 bytes를 나타내는 새
Uint8Array객체로 한다. -
Enqueue chunk를 datagrams.
[[Readable]]에 넣는다. -
Resolve promise를 undefined로 처리한다.
-
-
사용자 에이전트는 receiveDatagrams를
WebTransport
객체의
[[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 <ArrayBuffer >exportKeyingMaterial (BufferSource ,label optional BufferSource );context readonly attribute Promise <undefined >ready ;readonly attribute WebTransportReliabilityMode reliability ;readonly attribute WebTransportCongestionControl congestionControl ; [EnforceRange ]attribute unsigned short ?anticipatedConcurrentIncomingUnidirectionalStreams ; [EnforceRange ]attribute unsigned short ?anticipatedConcurrentIncomingBidirectionalStreams ;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이 설정되면 완료되고, 설정 과정이 실패하면 reject되는 promise. |
[[Reliability]]
| WebTransportReliabilityMode로,
첫 홉이 신뢰성 없는(UDP) 전송을 지원하는지 또는 신뢰성 있는(TCP 대체) 전송만 가능한지를 나타냄. 연결 전까지는 "pending" 반환.
|
[[CongestionControl]]
| WebTransportCongestionControl로,
애플리케이션이 처리량 또는 저지연에 최적화된 혼잡 제어 알고리즘을 선호하여 요청했는지, 또는 "default"인지를 나타냄.
|
[[AnticipatedConcurrentIncomingUnidirectionalStreams]]
| 애플리케이션이 서버가 생성할 것으로 예상하는 수신 단방향 스트림의 동시 개수 또는 null. |
[[AnticipatedConcurrentIncomingBidirectionalStreams]]
| 애플리케이션이 서버가 생성할 것으로 예상하는 양방향 스트림의 동시 개수 또는 null. |
[[Protocol]]
| 서버가 선택한 애플리케이션 레벨 프로토콜을 나타내는 문자열(있으면). 초기값은 빈 문자열. |
[[Closed]]
| 관련 WebTransport
객체가 정상적으로 종료되면 완료되고, 비정상적으로 종료되거나 초기화에 실패하면 reject되는 promise.
|
[[Draining]]
| 관련 WebTransport session이 drained되면 완료되는 promise. |
[[Datagrams]]
| WebTransportDatagramDuplexStream.
|
[[Session]]
| 이 WebTransport
객체의 WebTransport session 또는 null
|
[[NewConnection]]
| "no" 또는 "yes-and-dedicated" 중 하나.
|
[[RequireUnreliable]]
| UDP가 필수인지 여부를 나타내는 불리언. |
[[ServerCertificateHashes]]
| 리스트로,
0개 이상의 WebTransportHash
객체.
|
6.2. 생성자
WebTransport()
생성자가 호출되면, 사용자 에이전트는 다음 단계를 실행해야 한다:
-
baseURL을 this의 relevant settings object의 API base URL로 한다.
-
url을 URL record로, parsing
url과 baseURL의 결과로 한다. -
url이 failure라면, throw
SyntaxError예외를 발생시킨다. -
url의 scheme이
https가 아니면, throwSyntaxError예외를 발생시킨다. -
url의 fragment가 null이 아니면, throw
SyntaxError예외를 발생시킨다. -
allowPooling을
options의allowPooling으로 한다. -
dedicated를 allowPooling의 not 값으로 한다.
-
serverCertificateHashes를
options의serverCertificateHashes로 한다. -
dedicated가 false이고 serverCertificateHashes가 비어있지 않으면, throw
NotSupportedError예외를 발생한다. -
newConnection을 dedicated가 false면 "
no", 아니면 "yes-and-dedicated"로 한다. -
requireUnreliable를
options의requireUnreliable로 한다. -
congestionControl을
options의congestionControl로 한다. -
congestionControl이
"default"가 아니고, 사용자 에이전트가 congestionControl에 최적화된 혼잡제어 알고리즘을 지원하지 않으면, congestionControl을"default"로 설정. -
protocols 내의 값 중 중복되거나, WebTransport 프로토콜의 애플리케이션 프로토콜 값 조건에 맞지 않거나, isomorphic encoded 길이가 0이거나 512를 초과하면 throw
SyntaxError예외를 발생. -
anticipatedConcurrentIncomingUnidirectionalStreams를
options의anticipatedConcurrentIncomingUnidirectionalStreams로 한다. -
anticipatedConcurrentIncomingBidirectionalStreams를
options의anticipatedConcurrentIncomingBidirectionalStreams로 한다. -
datagramsReadableType을
options의datagramsReadableType로 한다. -
incomingDatagrams를 new
ReadableStream으로 한다. -
transport를 새로 생성한
WebTransport객체로 한다. 다음과 같이 설정:[[SendStreams]][[ReceiveStreams]][[IncomingBidirectionalStreams]][[IncomingUnidirectionalStreams]][[State]]-
"connecting" [[Ready]]-
새 promise
[[Reliability]]-
"pending"
[[CongestionControl]]-
congestionControl
[[AnticipatedConcurrentIncomingUnidirectionalStreams]]-
anticipatedConcurrentIncomingUnidirectionalStreams
[[AnticipatedConcurrentIncomingBidirectionalStreams]]-
anticipatedConcurrentIncomingBidirectionalStreams
[[Protocol]]-
빈 문자열
[[Closed]]-
새 promise
[[Draining]]-
새 promise
[[Datagrams]]-
undefined
[[Session]]-
null
[[NewConnection]]-
newConnection
[[RequireUnreliable]]-
requireUnreliable
[[ServerCertificateHashes]]-
serverCertificateHashes
-
transport.
[[Datagrams]]에 creatingWebTransportDatagramDuplexStream의 결과를 할당. 인자로는 transport, incomingDatagrams, datagramsReadableType 사용. -
pullDatagramsAlgorithm을 pullDatagrams를 transport로 실행하는 액션으로 한다.
Note: 데이터그램에 64 kibibytes 버퍼를 사용할 것을 권고하며, WebTransport 데이터그램 frame 크기의 상한이 QUIC의 최대 데이터그램 프레임 크기(권장 64 kibibytes)이므로, 이를 초과하는 경우 스트림 오류 예방 목적임.
-
datagramsReadableType이
"bytes"면, set up with byte reading support incomingDatagrams의 pullAlgorithm에 pullDatagramsAlgorithm을 설정하고, highWaterMark 를 0으로 설정. 아니면, set up incomingDatagrams의 pullAlgorithm에 pullDatagramsAlgorithm을, highWaterMark를 0으로 설정. -
pullBidirectionalStreamAlgorithm을 pullBidirectionalStream 을 transport를 인자로 실행하는 액션으로 한다.
-
Set up transport.
[[IncomingBidirectionalStreams]]의 pullAlgorithm에 pullBidirectionalStreamAlgorithm을, highWaterMark에 0을 설정. -
pullUnidirectionalStreamAlgorithm을 pullUnidirectionalStream 을 transport를 인자로 실행하는 액션으로 한다.
-
Set up transport.
[[IncomingUnidirectionalStreams]]의 pullAlgorithm에 pullUnidirectionalStreamAlgorithm을, highWaterMark에 0을 설정. -
client를 transport의 relevant settings object로 한다.
-
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, redirect mode는 "error"로 한다.Note: 리다이렉트는 따라가지 않는다. 네트워크 오류와 리다이렉션 오류는 구분불가. 교차 오리진 상황에서 CORS로 막을 정보를 노출하지 않기 위한 정책임. 동일 오리진일 때 handshake 남용 방지 목적도 있음.
-
request의 method를 "
CONNECT"로 하고,:protocolpseudo-header를"webtransport"로 한다. -
protocols가 비어있지 않으면, (
WT-Available-Protocols, structured header list에 structured header string 아이템을 protocols 순서대로 포함)로 set a structured field value를 request의 header list에 설정. -
Fetch request를 useParallelQueue를 true로, processResponse 에는 response를 받으면 다음 단계를 실행하는 것으로 설정:
-
Process a WebTransport fetch response를 response, origin, protocols, congestionControl로 호출.
-
-
transport를 반환한다.
-
transport를
WebTransport으로, request와 연관된 객체로 한다. -
url을 request의 current URL로 한다.
-
newConnection을 transport.
[[NewConnection]]로 한다. -
requireUnreliable을 transport.
[[RequireUnreliable]]로 한다. -
serverCertificateHashes를 transport.
[[ServerCertificateHashes]]의 값들로 한다. -
connection을 obtaining a connection을 networkPartitionKey, url, false, newConnection, requireUnreliable를 인자로 호출한 결과로 한다. 이 때 serverCertificateHashes가 비어 있지 않으면 디폴트 인증서 검증 대신, custom certificate requirements를 만족하고, verifying the certificate hash가 serverCertificateHashes에 대해 true를 반환해야 유효한 것으로 간주. 둘 중 하나라도 만족하지 않으면 failure.
-
connection이 failure면 failure 반환.
-
connection이 첫 SETTINGS frame을 받을 때까지 기다리고, settings를 그 SETTINGS frame을 나타내는 딕셔너리로 한다.
-
settings에
SETTINGS_ENABLE_CONNECT_PROTOCOL(0x08, Section 3 of [RFC8441] for HTTP/2; 0x08, Section 3 of [RFC9220])의 값이 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.
Note:
SETTINGS_WT_MAX_SESSIONS는 IETF에서 변경 가능성이 있으며SETTINGS_ENABLE_WEBTRANSPORT로 되돌릴 수 있음. -
-
connection을 반환.
-
response가 network error면, 남은 단계를 중단하고 queue a network task를 transport로 다음 단계를 실행:
-
transport.
[[State]]가"closed"또는"failed"면 단계를 중단. -
error를 새로 생성한
WebTransportError로 하고,source는"session"으로 한다. -
Cleanup transport을 error로 한다.
-
-
connection을 response와 연관된 underlying connection으로 한다.
-
[WEB-TRANSPORT-OVERVIEW] Section 4.1의 제한을 따라 WebTransport session 확립을 connection과 서버의 response로 진행.
-
session을 위에서 확립된 WebTransport session으로 한다. 이때 생성되는 underlying transport stream을 session의 CONNECT stream이라 칭함.
Note: 이 단계는 [QUIC-DATAGRAM] 명시된 파라미터 교환 마무리도 포함.
-
이전 단계가 실패하면 남은 단계를 중단하고 queue a network task를 transport로 다음 단계 실행:
-
transport.
[[State]]가"closed"또는"failed"면 단계를 중단. -
error를 새로 생성한
WebTransportError로 하고,source는"session"으로 한다. -
Cleanup transport을 error로 한다.
-
-
사용자 에이전트가 혼잡제어 알고리즘을 여러 개 지원하면, 본 connection의 송신 데이터에 congestionControl에 맞는 것을 선택.
-
Queue a network task를 transport로 다음 단계 실행:
-
단언: this의
[[Datagrams]]의[[OutgoingMaxDatagramSize]]는 정수임. -
transport.
[[State]]가"connecting"이 아니면:-
in parallel로, terminate session
-
단계를 중단한다.
-
-
transport.
[[State]]를"connected"로 한다. -
transport.
[[Session]]를 session으로 설정. -
transport.
[[Protocol]]에, 협상된 애플리케이션 프로토콜의 문자열 값이 있으면 그 값, 아니면""로 설정. -
연결이 HTTP/3이면 transport.
[[Reliability]]를"supports-unreliable"로 설정. -
연결이 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로 한다.
-
다음 단계를 in parallel로 실행:
-
session에서 available incoming bidirectional stream이 될 때까지 대기
-
internalStream을 receiving a bidirectional stream에서 session으로 얻는다.
-
Queue a network task를 transport로 다음 단계 실행:
-
stream을 creating
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로 한다.
-
다음 단계를 in parallel로 실행:
-
session에 available incoming unidirectional stream이 될 때까지 대기
-
internalStream을 receiving an incoming unidirectional stream에서 session으로 얻는다.
-
Queue a network task를 transport로 다음 단계를 실행:
-
stream을 creating
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를
설정해도
애플리케이션이 예상한 수 만큼 스트림을 반드시 수신할 것이라는 보장은 없음.
protocol, DOMString 타입, readonly-
WebTransport 세션이 설정되고
protocols생성자 옵션에서 비어 있지 않은 배열이 주어졌을 때, 서버가 선택한 애플리케이션 레벨 프로토콜(있는 경우)를 반환. 그렇지 않으면 빈 문자열을 반환. getter 단계는 this의[[Protocol]]를 반환.
6.4. 메서드
close(closeInfo)-
WebTransport 객체와 연관된 WebTransport session을 종료한다.
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 인코드 prefix의 길이가 1024를 넘지 않는 경우로 한다. -
reason을 reasonString의 UTF-8 인코딩 값으로 한다.
-
in parallel로, terminate session을 code와 reason을 전달하여 실행한다.
Note: 이는 sending 중단와 receiving 중단을 transport.
[[SendStreams]]및[[ReceiveStreams]]에 포함된 WebTransport stream 모두에 대해 수행한다. -
Cleanup transport를
AbortError및 closeInfo와 함께 호출한다.
-
getStats()-
이
WebTransport의 underlying connection 에 대한 통계를 비동기로 수집하고 결과를 제공한다.getStats 호출 시, 사용자 에이전트는 다음 단계를 실행해야 한다:
-
transport를 this로 한다.
-
p를 새 promise로 한다.
-
transport.
[[State]]가"failed"이면, reject p와 함께InvalidStateError를 반환하고, 단계를 중단. -
다음 단계를 in parallel로 실행:
-
transport.
[[State]]가"connecting"이면, 변경될 때까지 대기한다. -
transport.
[[State]]가"failed"면, queue a network task로 transport에 대해 reject p을InvalidStateError로 반환하고 단계를 중단한다. -
transport.
[[State]]가"closed"면, queue a network task로 transport에 대해 resolve p을 해당 connection에서 수집된 최신 통계로 반환한다. 통계 수집 시점은 구현정의이다. -
gatheredStats를 list로, underlying connection에서
WebTransportConnectionStats와WebTransportDatagramStats의 딕셔너리 멤버를 정확히 채우기에 필요한 통계 항목으로 한다. -
queue a network task로 transport에 대해 다음 단계 실행:
-
stats를 new
WebTransportConnectionStats객체로 한다. -
datagramStats를 new
WebTransportDatagramStats객체로 한다. -
stats["
datagrams"] 에 datagramStats를 할당. -
stats와 datagramStats의 각 member 중 노출하고 싶은 값에 대해, set member를 gatheredStats의 entry에서 얻은 값으로 할당한다.
-
Resolve p에 stats를 할당.
-
-
-
p를 반환한다.
-
exportKeyingMaterial(BufferSource label, optional BufferSource context)-
이
WebTransport의 TLS Keying Material Exporter로부터 TLS 세션에 고유하게 연관된 underlying connection 에서 keying material을 추출한다.exportKeyingMaterial이 호출되면, 사용자 에이전트는 다음을 실행해야 한다:-
transport를 this로 한다.
-
labelLength를 label의 byte length로 한다.
-
labelLength가 255를 초과하면 a promise rejected with
RangeError를 반환. -
contextLength를 0으로 한다.
-
context가 주어졌으면 contextLength를 context의 byte length로 한다.
-
contextLength가 255를 초과하면 a promise rejected with
RangeError를 반환. -
p를 새 promise로 한다.
-
다음 단계를 in parallel로 실행하되, abort when transport의
[[State]]가"closed"나"failed"가 되면, 대신 queue a network task와 transport로 reject p을InvalidStateError로 반환한다:-
keyingMaterial을 [WEB-TRANSPORT-OVERVIEW] Section 4.1에 정의된 대로 labelLength, label, contextLength 및 context로 TLS keying material을 export한 결과로 한다.
-
queue a network task로 transport와, resolve p를 keyingMaterial로 한다.
-
-
p를 반환한다.
-
createBidirectionalStream()-
출력용 양방향 스트림을 위한
WebTransportBidirectionalStream객체를 생성한다. 스트림을 생성해도 피어가 즉시 이를 인지하지 않으며, 실제 데이터가 전송되어야 인지할 수도 있다.Note: 스트림이 생성되어도 실제 데이터가 보내지기 전까지 서버에서 인지하지 못할 수 있다.
createBidirectionalStream호출 시, 사용자 에이전트는 다음 단계를 실행해야 한다:-
this.
[[State]]가"closed"나"failed"면 rejected promise를InvalidStateError로 반환. -
sendGroup이 null이 아니고 sendGroup.
[[Transport]]가 this와 다르면, throwInvalidStateError. -
waitUntilAvailable을
options의waitUntilAvailable로 한다. -
p를 새 promise로 한다.
-
transport를 this로 한다.
-
다음 단계를 in parallel로 실행(단, abort when transport.
[[State]]가"closed"나"failed"가 되면 queue a network task로 transport와, reject p을InvalidStateError로 반환한다):-
streamId를 transport.
[[Session]]에서 사용 가능한 새 스트림 ID(중복/불가용 시 아래 참고)에 할당. 할당 불가 시,waitUntilAvailable이 true면 대기, 아니면 queue a network task 후 reject p을QuotaExceededError로 반환. -
internalStream을 creating a bidirectional stream에서 transport.
[[Session]]과 streamId로 얻는다. -
queue a network task 로 transport에 대해 다음 실행:
-
transport.
[[State]]가"closed"나"failed"면, reject p를InvalidStateError로 반환, 단계 중단. -
stream을 creating
WebTransportBidirectionalStream에서 internalStream, transport, sendGroup, sendOrder로 새로 생성. -
Resolve p에 stream 할당함.
-
-
-
p를 반환한다.
-
createUnidirectionalStream()-
출력용 단방향 스트림을 위한
WebTransportSendStream을 생성한다. 스트림을 생성해도 서버가 인지하지 못하며 실제 데이터가 전송되어야 인지할 수 있다.Note: 스트림이 생성되어도 실제 데이터가 보내지기 전까지 서버가 인지하지 못할 수 있다.
createUnidirectionalStream()호출 시, 사용자 에이전트는 다음 단계를 실행해야 한다:-
this.
[[State]]가"closed"나"failed"면 rejected promise를InvalidStateError로 반환. -
sendGroup이 null이 아니고 sendGroup.
[[Transport]]가 this와 다르면, throwInvalidStateError. -
waitUntilAvailable을
options의waitUntilAvailable로 한다. -
p를 새 promise로 한다.
-
transport를 this로 한다.
-
다음 단계를 in parallel로 실행(단, abort when transport.
[[State]]가"closed"나"failed"가 되면 queue a network task로 transport와, reject p을InvalidStateError로 반환한다):-
streamId를 transport.
[[Session]]에서 사용할 수 있는 새 스트림 ID로 (불가 시 아래 참조), waitUntilAvailable이 true면 대기, 아니면 queue a network task 후 reject p을QuotaExceededError로 반환. -
internalStream을 creating an outgoing unidirectional stream에서 transport.
[[Session]]과 streamId로 얻는다. -
queue a network task 로 transport에 대해 다음 실행:
-
transport.
[[State]]가"closed"나"failed"면, reject p를InvalidStateError로 반환, 단계 중단. -
stream을 creating
WebTransportSendStream에서 internalStream, transport, sendGroup, sendOrder로 새로 생성. -
Resolve p에 stream 할당함.
-
-
-
p를 반환한다.
-
createSendGroup()-
WebTransportSendGroup을 생성한다.createSendGroup()가 호출되면 사용자 에이전트는 다음을 실행해야 한다:-
this.
[[State]]가"closed"나"failed"면 throwInvalidStateError. -
creating
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 ;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 session이 어떻게 설정되고 사용되는지를 결정한다.
allowPooling, of type boolean, defaulting tofalse-
true로 설정하면, WebTransport 세션이 풀링될 수 있다. 즉, 해당 세션의 underlying connection 을(를) 다른 WebTransport 세션과 공유할 수 있다.
requireUnreliable, of type boolean, defaulting tofalse-
true로 설정하면, WebTransport 세션은 HTTP/2 연결에서는 설정될 수 없으며, 반드시 HTTP/3 연결이 가능해야 한다.
serverCertificateHashes, of type sequence<WebTransportHash>, defaulting to[]-
이 옵션은 dedicated 연결을 사용하는 트랜스포트에서만 지원된다. 이 기능을 지원하지 않는 트랜스포트 프로토콜에서 이 필드가 비어 있지 않으면,
NotSupportedError예외가 발생해야 한다.지원되고 비어 있지 않으면, user agent는 서버 인증서가 certificate hash 검증에 성공하고
serverCertificateHashes및 custom certificate requirements를 모두 만족할 때에만 신뢰해야 한다. user agent는 알 수 없는algorithm해시를 무시해야 한다. 비어 있으면, user agent는 일반 fetch 요청에서 사용하는 인증서 검증을 사용해야 한다.이 옵션은
allowPooling과 함께 사용할 수 없다. congestionControl, of type WebTransportCongestionControl, defaulting to"default"-
애플리케이션이 처리량 또는 저지연에 특화된 혼잡 제어 알고리즘을 사용할 것을 선호하는 경우 설정할 수 있다. 이 값은 user agent에게 힌트를 제공한다.
anticipatedConcurrentIncomingUnidirectionalStreams, of type unsigned short, nullable, defaulting tonull-
애플리케이션이 서버가 개설할 것으로 예상하는 동시에 열린 수신 단방향 스트림 수를 지정할 수 있다. user agent는 서버에서 최소 100개의 수신 단방향 스트림을 허용해야 한다. null이 아니면, user agent는
[[AnticipatedConcurrentIncomingUnidirectionalStreams]]값을 서버와의 협상에 반영해서 왕복 횟수 감소를 시도해야 한다. anticipatedConcurrentIncomingBidirectionalStreams, of type unsigned short, nullable, defaulting tonull-
애플리케이션이 서버가 개설할 것으로 예상하는 동시에 열린 양방향 스트림 수를 지정할 수 있다. user agent는 서버에서 최소 100개의 양방향 스트림 생성을 허용해야 한다. null이 아니면, user agent는
[[AnticipatedConcurrentIncomingBidirectionalStreams]]값을 서버와 협상에 반영해서 왕복 횟수 감소를 시도해야 한다. protocols, of type sequence<DOMString>, defaulting to[]-
애플리케이션 레벨의 protocol names 배열을 선택적으로 제공한다. 선호하는 애플리케이션 프로토콜을 선택하고 클라이언트에 통보하는 것은 서버에서 옵션이다. 적합한 프로토콜이 제공되지 않으면 서버에서 요청을 거절할 수 있다.
datagramsReadableType, of type ReadableStreamType-
수신 데이터그램에 대해 readable byte stream을 사용하고자 하는 애플리케이션의 선호를 명시적으로 지정 가능하다. 지정하지 않으면 기본 readable stream이 사용된다.
Note: readable stream은 데이터그램 의미와 호환되지만, readable byte stream은 호환되지 않는다. 데이터그램은 0바이트 이상의 독립 메시지이며 순서가 보장되지 않고 도착할 수 있다(단순 바이트 시퀀스가 아님). 빈 데이터그램은 손실되고,
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 session의 underlying connection에 대한
WebTransport 특화 통계 정보를 포함한다.
Note: 풀링이 사용되는 경우, 동일한 WebTransport sessions이 동일한 connection에 풀링되면 모두 동일한 정보를 받는다. 즉, 동일한 network partition key를 보유한 풀링된 sessions 간에 정보가 공개된다.
Note: 사용 불가능한 통계는 WebTransportConnectionStats
사전에서 absent 상태가 된다.
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-
underlying connection을 통해 전송된 payload 바이트 수 (프레이밍 오버헤드, 재전송 제외)
bytesSentOverhead, 타입 unsigned long long-
bytesSent만큼의 payload 바이트를 underlying connection 에서 전송할 때 소요된 프레이밍 및 재전송 오버헤드 (바이트 단위) bytesAcknowledged, 타입 unsigned long long-
서버가 QUIC ACK 메커니즘을 통해 수신을 인지한 payload 바이트 수 (underlying connection, 프레이밍은 포함하지 않음)
Note: 일반적으로
bytesSent보다 작으며 패킷 손실로 인해 영구적으로 작을 수도 있음.bytesAcknowledged은(는) 구현 가능성 문제로 Working Group이 위험요소로 지정함. packetsSent, 타입 unsigned long long-
underlying connection 에서 전송된 전체 패킷 수 (손실된 패킷 포함)
bytesLost, 타입 unsigned long long-
underlying connection 에서 손실된 바이트 수 (단조 증가하지 않음, 손실로 선언했던 패킷이 뒤늦게 수신될 수 있음). UDP 등 외부 프레이밍 포함 않음.
packetsLost, 타입 unsigned long long-
underlying connection 에서 손실된 패킷 수 (단조 증가하지 않음, 손실로 선언했던 패킷이 뒤늦게 수신될 수 있음)
bytesReceived, 타입 unsigned long long-
underlying connection 에서 수신된 전체 바이트 수(스트림 중복 데이터 포함, UDP 등 외부 프레이밍 제외)
packetsReceived, 타입 unsigned long long-
underlying connection 에서 수신된 전체 패킷 수(처리 불가 패킷도 포함)
smoothedRtt, 타입 DOMHighResTimeStamp-
현재 해당 연결에서 관찰되는 smoothed RTT. [RFC9002] Section 5.3 참조.
rttVariation, 타입 DOMHighResTimeStamp-
현재 연결에서 관찰되는 RTT 샘플의 평균 변동값. [RFC9002] Section 5.3 참조.
minRtt, 타입 DOMHighResTimeStamp-
전체 연결에서 관찰된 최소 RTT. [RFC9002] Section 5.2 참조.
estimatedSendRate, 타입 unsigned long long, nullable, 기본값null-
user agent가 큐에 쌓인 데이터를 초당 몇 비트로 전송할지 추정치(모든 스트림/데이터그램에 적용). 해당 WebTransport session에 공유되는 모든 데이터에 적용되며, 혼잡 제어 알고리즘(
congestionControl으로 선택 가능)이 산출한다. 프레이밍 오버헤드는 미포함, 애플리케이션 payload의 전송 가능 속도를 의미. user agent가 추정치를 제공하지 않으면null. 이전 결과가 null이 아니었어도 null이 될 수 있음. atSendCapacity, 타입 boolean, 기본값false-
false면
estimatedSendRate가 애플리케이션 때문에 제한되어 있을 수 있음(애플리케이션에서 혼잡제어로 허용되는 양보다 훨씬 적게 보냄). 이때 혼잡제어 알고리즘에서 네트워크 용량 추정이 부정확할 수 있음.true면 애플리케이션이 네트워크 용량만큼 전송하며
estimatedSendRate가 네트워크 용량을 반영.atSendCapacity가true면estimatedSendRate는 상한치에 해당함. 애플리케이션 전송 속도가 유지되면estimatedSendRate는 네트워크 상황에 맞게 조정됨. 단,atSendCapacity가 true여도estimatedSendRate가null일 수 있음.
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, nullable-
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로 한다.
-
다음 단계를 in parallel로 실행:
-
gatheredStats를 list로, this
WebTransportSendStream에 특화된 통계를WebTransportSendStreamStats의 딕셔너리 멤버에 정확히 할당하게 준비합니다. -
Queue a network task를 transport로 다음 단계를 실행:
-
-
p를 반환.
-
getWriter()-
이 메서드는
getWriter와 동일한 방법으로 구현해야 하며, 단WritableStream에서 상속되는 대신WritableStreamDefaultWriter를 생성하는 것이 아니라, WebTransportWriter를WebTransportWriter로 this와 함께 생성해야 합니다.
7.3. 내부 슬롯
WebTransportSendStream
객체는 다음과 같은 내부 슬롯을 가진다.
| 내부 슬롯 | 설명 (비규범적) |
|---|---|
[[InternalStream]]
| outgoing unidirectional 또는 bidirectional WebTransport 스트림 |
[[PendingOperation]]
| 진행 중인 쓰기 또는 닫기 작업을 나타내는 프라미스, 또는 null |
[[Transport]]
| 이 WebTransport
객체가 소유한 WebTransportSendStream.
|
[[SendGroup]]
| 선택적 WebTransportSendGroup,
또는 null
|
[[SendOrder]]
| 옵션 전달 순서 번호, 기본값은 0 |
[[AtomicWriteRequests]]
| 순서가 지정된 집합의 프라미스 모음으로, underlying sink에 큐잉된 요청 중 atomic 처리가 필요한 쓰기 요청들을 추적 |
[[BytesWritten]]
| 스트림에 기록된 바이트 수 |
[[CommittedOffset]]
| 스트림에서 피어에게 전달될 바이트 수를 기록하는 오프셋. 스트림이 sending 중단 상태여도 값을 유지함; 참조: [RELIABLE-RESET] |
7.4. 절차
생성하려면
WebTransportSendStream
을,
송신 단방향 또는
양방향
WebTransport 스트림
internalStream, WebTransport
transport, sendGroup, sendOrder와 함께 다음 단계를 수행한다:
-
stream을 new
WebTransportSendStream로 생성합니다. 다음과 같이 초기화됩니다:[[InternalStream]]-
internalStream
[[PendingOperation]]-
null
[[Transport]]-
transport
[[SendGroup]]-
sendGroup
[[SendOrder]]-
sendOrder
[[AtomicWriteRequests]]-
비어 있는 ordered set의 promise 집합
[[BytesWritten]]-
0
[[CommittedOffset]]-
0
-
writeAlgorithm을 chunk를 stream에 쓰기 위한 동작으로 둡니다.
-
closeAlgorithm을 stream을 닫기 위한 동작으로 둡니다.
-
abortAlgorithm을 reason과 함께 stream을 중단하는 동작으로 둡니다.
-
Set up stream에 writeAlgorithm을 writeAlgorithm으로, closeAlgorithm을 closeAlgorithm으로, abortAlgorithm을 abortAlgorithm으로 설정합니다.
-
abortSignal을 stream의 [[controller]].[[abortController]].[[signal]]로 둡니다.
-
다음 단계를 abortSignal에 추가합니다.
-
pendingOperation을 stream.
[[PendingOperation]]로 둡니다. -
pendingOperation이 null이면, 이 단계들을 중단합니다.
-
stream.
[[PendingOperation]]를 null로 설정합니다. -
reason을 abortSignal의 abort reason으로 둡니다.
-
promise를 중단 stream with reason의 결과로 둡니다.
-
Upon fulfillment of promise, reject pendingOperation을 reason으로 거절합니다.
-
-
Append stream을 transport.
[[SendStreams]]에 추가합니다. -
stream을 반환합니다.
WebTransportSendStream
stream에 쓰기 위해, 다음 단계를 수행한다:
-
transport에 stream.
[[Transport]]를 할당한다. -
chunk가
BufferSource가 아니라면, TypeError로 거부된 promise를 반환한다. -
promise에 새로운 promise를 할당한다.
-
bytes에 chunk가 나타내는 바이트 시퀀스의 복사본을 할당한다.
-
stream.
[[PendingOperation]]에 promise를 할당한다. -
inFlightWriteRequest에 stream.inFlightWriteRequest를 할당한다.
-
atomic에 stream.
[[AtomicWriteRequests]]가 inFlightWriteRequest를 포함하고 있다면 true, 아니면 false를 할당한다. -
다음 단계를 병렬로 실행한다:
-
atomic이 true이고 현재 플로우 제어 윈도우가 bytes 전체를 전송하기에 너무 작으면 남은 단계를 중단하고 네트워크 작업 큐에서 transport로 다음 하위 단계를 실행한다:
-
stream.
[[PendingOperation]]을 null로 설정한다. -
모든 atomic write 요청 중단을 stream에 대해 실행한다.
-
-
그렇지 않으면, send bytes을(를) stream.
[[InternalStream]]에서 전송하고 그 작업이 완료될 때까지 기다린다. 이 전송은 이전에 대기 중이었던 스트림, 데이터그램 및 앞으로 대기할 스트림/데이터그램 전송과 섞여 동작할 수 있다.사용자 에이전트는 성능 향상을 위해 버퍼를 사용할 수 있다. 이 버퍼는 고정된 상한을 두어,
WebTransportSendStream사용자가 backpressure 정보를 알 수 있도록 해야 한다.이 전송은
[[SendGroup]]이 같고[[SendOrder]]가 더 높은(더 우선순위가 높은) 스트림들 중 에러가 아니고 플로우 제어에 막혀있지 않은 모든 바이트가 먼저 전송될 때까지 block되어야 한다.stream.
[[SendOrder]]는 이 병렬 동작 내에서 접근한다.사용자 에이전트는 이러한 값이 전송 도중 라이브업데이트되는 것에도 동적으로 반응해야 하나, 구체적인 방식은 구현 정의이다.
Note: 재전송 순서에 대한 정의는 구현 정의이다. 그러나 데이터가 높은
[[SendOrder]]값을 가질수록 우선적으로 재전송되어야 한다.이 전송은 플로우 제어 또는 에러 이외에는 starvation이 발생해서는 안 된다.
사용자 에이전트는 starvation이 아닌 모든 스트림에 대역폭을 공정하게 할당해야 한다.
Note: 여기서 공정성의 정의는 구현 정의이다.
-
이전 단계가 네트워크 오류로 실패했다면, 남은 단계를 중단한다.
Note: 여기에서 promise를 거부하지 않는데, 네트워크 오류는 별도 경로로 처리되며 해당 단계에서 stream.
[[PendingOperation]]이 reject된다. -
그 외의 경우, 네트워크 작업 큐에서 transport로 아래 단계를 실행한다:
-
stream.
[[PendingOperation]]을 null로 설정한다. -
bytes의 길이를 stream.
[[BytesWritten]]에 더한다. -
stream.
[[AtomicWriteRequests]]가 inFlightWriteRequest를 포함한다면, 해당 요청 삭제를 수행한다. -
Resolve promise를 undefined로 해결한다.
-
-
-
promise를 반환한다.
Note: 이 알고리즘(혹은, write(chunk))
에서 반환된 promise의 이행은,
해당 chunk가 서버에 ack되었다는 의미가 아님에 유의해야 한다.
단지 해당 chunk가 버퍼에 추가되었음을 의미할 수 있다.
서버에 도달했는지 확인하려면, 서버에서 응용 레벨의 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와 연관된 바이트의 전송을 중단한다.
7.5. 서버로부터 수신 중단 신호 받기
WebTransport stream이 WebTransportSendStream
stream과 연관되어 있고 서버로부터
receiving aborted 신호를 받으면, 다음 단계를 수행한다:
-
transport를 stream.
[[Transport]]로 둔다. -
code를 receiving aborted 신호에 첨부된 애플리케이션 프로토콜 오류 코드로 둔다.
Note: code의 유효 값은 0부터 4294967295(포함)까지이다. underlying connection이 HTTP/3을 사용 중인 경우, 해당 코드는 [WEB-TRANSPORT-HTTP3]에 서술된 대로 [0x52e4a40fa8db, 0x52e5ac983162] 범위의 숫자로 인코딩된다.
-
Queue a network task를 transport로 수행하여 다음 단계를 실행한다:
-
transport.
[[State]]가"closed"또는"failed"이면, 이 단계들을 중단한다. -
Remove를 수행하여 stream을 transport.
[[SendStreams]]에서 제거한다. -
error를 새로 created한
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은
생성 시 또는 sendGroup 속성 할당을 통해,
언제든지 최대 하나의 그룹(grouped)
WebTransportSendGroup에
속할 수 있습니다.
기본적으로 이들은 그룹에 속하지 않음(ungrouped) 상태입니다.
유저 에이전트는 WebTransportSendGroup들에
대해 WebTransportSendStream
전송을 위한 대역폭 할당 시 동등하게 간주합니다.
각 WebTransportSendGroup은
sendOrder
평가를 위한 독립적인 번호 공간도 제공합니다.
[Exposed =(Window ,Worker ),SecureContext ]interface {WebTransportSendGroup Promise <WebTransportSendStreamStats >getStats (); };
WebTransportSendGroup
은 항상
create 절차에 의해 생성됩니다.
8.1. 메서드
getStats()-
이 sendGroup 하위에
WebTransportSendStream에 grouped된 모든 스트림의 통계를 집계하여 비동기적으로 결과를 보고한다.getStats가 호출되면 사용자 에이전트는 다음 단계를 실행해야 한다:
-
p를 새 promise로 한다.
-
streams를
WebTransportSendStream중[[SendGroup]]이 this인 모든 스트림으로 한다. -
다음 단계를 in parallel로 실행:
-
gatheredStats를 streams 내 모든 스트림의 집계 통계(
WebTransportSendStreamStats의 딕셔너리 멤버에 정확히 할당 가능한 값) 리스트로 한다. -
Queue a network task를 transport와 함께 다음 단계 실행:
-
-
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로 둔다.
-
다음 단계를 병렬로(In parallel) 수행한다:
-
gatheredStats를, list 형태의 통계로 두되 this
WebTransportReceiveStream에 특화된 값으로서,WebTransportReceiveStreamStats의 dictionary members를 정확히 채우는 데 필요하다. -
Queue a network task를 transport로 수행하여 다음 단계를 실행한다:
-
-
p를 반환한다.
-
9.2. 내부 슬롯
WebTransportReceiveStream
객체는 다음과 같은 내부 슬롯을 가지고 있습니다.
| 내부 슬롯 | 설명 (비규범적) |
|---|---|
[[InternalStream]]
| 수신 단방향 또는 양방향 WebTransport 스트림. |
[[Transport]]
| 이 WebTransport
객체가 WebTransportReceiveStream을
소유합니다.
|
9.3. 절차
create를 수행하여
WebTransportReceiveStream을
만들고,
incoming unidirectional 또는 bidirectional WebTransport stream
internalStream 및 WebTransport
transport가 주어졌을 때 다음 단계를 수행한다:
-
stream을 new로 생성한
WebTransportReceiveStream으로 두고, 다음과 같이 설정한다:[[InternalStream]]-
internalStream
[[Transport]]-
transport
-
pullAlgorithm을, pulls bytes를 통해 stream에서 바이트를 끌어오는 동작으로 둔다.
-
cancelAlgorithm을, cancels를 사용해 reason을 주어 stream을 취소하는 동작으로 둔다.
-
Set up with byte reading support를 stream에 대해 수행하되, pullAlgorithm을 pullAlgorithm으로, cancelAlgorithm을 cancelAlgorithm으로 설정한다.
-
Append를 수행하여 stream을 transport의
[[ReceiveStreams]]에 추가한다. -
stream을 반환한다.
WebTransportReceiveStream
stream에서 pull bytes를 수행하려면,
다음 단계를 실행한다.
-
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의 byte length로 설정한다.
-
buffer를 stream의 current BYOB request view의 underlying buffer로 설정한다.
-
-
그 외의 경우:
-
offset을 0으로 설정한다.
-
maxBytes를 implementation-defined 크기로 설정한다.
-
buffer를 new
ArrayBuffer로, 크기를 maxBytes로 하여 생성한다. 만약ArrayBuffer할당에 실패하면, a promise rejected with를 통해RangeError를 반환한다.
-
-
다음 단계를 In parallel로 수행한다:
-
Write를 수행하여, read된 바이트를 internalStream에서 buffer에 offset 위치부터 최대 maxBytes 바이트까지 기록한다. 최소 한 바이트가 읽히거나 FIN이 수신될 때까지 대기한다. read를 읽힌 바이트 수로, hasReceivedFIN을 FIN이 동반되었는지 여부로 둔다.
사용자 에이전트는 전송 성능을 개선하기 위한 버퍼를 가질 수 있다. 이러한 버퍼는 서버로의 역압(backpressure) 정보를 전달하기 위해 고정된 상한을 가져야 한다(SHOULD).
Note: 이 동작은 buffer를 전부 채우기 전에 반환될 수 있다.
-
이전 단계가 실패하면, 남은 단계를 중단한다.
Note: 여기서는 promise를 reject하지 않는다. 네트워크 오류는 다른 곳에서 처리되며, 그 단계들은 error를 통해 stream을 에러 상태로 만들고, 이 pull을 대기 중인 모든 읽기 요청을 reject한다.
-
Queue a network task를 transport로 수행하여 다음 단계를 실행한다:
Note: 위에서 설명한 버퍼가 이 절차가 실행되는 event loop에서 사용 가능하면, 다음 단계는 즉시 실행될 수 있다.
-
만약 read > 0이면:
-
view를 새로운
Uint8Array로, buffer, offset, read를 사용하여 설정한다. -
Enqueue를 수행하여 view를 stream에 넣는다.
-
-
hasReceivedFIN이 true이면:
-
Remove를 수행하여 stream을 transport의
[[ReceiveStreams]]에서 제거한다. -
Close를 수행하여 stream을 닫는다.
-
-
Resolve를 수행하여 promise를 undefined로 해결한다.
-
-
-
promise를 반환한다.
WebTransportReceiveStream
stream을 reason과 함께 취소(cancel)하려면, 다음 단계를 수행한다.
-
transport를 stream.
[[Transport]]로 둔다. -
internalStream을 stream.
[[InternalStream]]로 둔다. -
promise를 새로운 promise로 둔다.
-
code를 0으로 둔다.
-
만약 reason이
WebTransportError이고 reason.[[StreamErrorCode]]가 null이 아니면, code를 reason.[[StreamErrorCode]]로 설정한다. -
만약 code < 0이면, code를 0으로 설정한다.
-
만약 code > 4294967295이면, code를 4294967295로 설정한다.
Note: code의 유효 값은 0부터 4294967295(포함)까지이다. underlying connection이 HTTP/3를 사용 중인 경우, 해당 코드는 [WEB-TRANSPORT-HTTP3]에 서술된 대로 [0x52e4a40fa8db, 0x52e5ac983162] 범위의 숫자로 인코딩된다.
-
Remove를 수행하여 stream을 transport의
[[SendStreams]]에서 제거한다. -
다음 단계를 In parallel로 수행한다:
-
Abort receiving를 internalStream에 대해 code로 수행한다.
-
Queue a network task를 transport로 수행하여 다음 단계를 실행한다:
Note: 위에서 설명한 버퍼가 이 절차가 실행되는 event loop에서 사용 가능하면, 다음 단계는 즉시 실행될 수 있다.
-
Remove를 수행하여 stream을 transport의
[[ReceiveStreams]]에서 제거한다. -
Resolve를 수행하여 promise를 undefined로 해결한다.
-
-
-
promise를 반환한다.
9.4. 서버로부터 송신 중단 신호 받기
WebTransportReceiveStream
stream과 연관된 WebTransport stream에 대해 다음 단계를 수행한다:
-
transport를 stream.
[[Transport]]로 둔다. -
code를 sending aborted 신호에 첨부된 애플리케이션 프로토콜 오류 코드로 둔다.
Note: code의 유효 값은 0부터 4294967295(포함)까지이다. underlying connection이 HTTP/3를 사용 중인 경우, 해당 코드는 [WEB-TRANSPORT-HTTP3]에 설명된 대로 [0x52e4a40fa8db, 0x52e5ac983162] 범위의 숫자로 인코딩된다.
-
Queue a network task를 transport로 수행하여 다음 단계를 실행한다:
-
transport.
[[State]]가"closed"또는"failed"이면, 이 단계들을 중단한다. -
Remove를 수행하여 stream을 transport의
[[ReceiveStreams]]에서 제거한다. -
error를 새로 created한
WebTransportError로 두되, 그source는"stream"이고streamErrorCode는 code로 한다. -
Error를 수행하여 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, readonly-
getter 단계: this의
[[Readable]]를 반환한다. writable, 타입 WebTransportSendStream, readonly-
getter 단계: this의
[[Writable]]를 반환한다.
10.3. 절차
create를 수행하여 WebTransportBidirectionalStream을
생성하기 위해,
bidirectional
WebTransport stream internalStream, WebTransport
객체 transport, 그리고 sendOrder가 주어졌을 때 다음 단계를 수행한다.
-
readable을 creating을 통해 얻은
WebTransportReceiveStream의 결과로 두되, internalStream과 transport를 사용한다. -
writable을 creating을 통해 얻은
WebTransportSendStream의 결과로 두되, internalStream, transport, 그리고 sendOrder를 사용한다. -
stream을 new로 생성한
WebTransportBidirectionalStream으로 두며, 다음과 같이 한다:[[Readable]]-
readable
[[Writable]]-
writable
[[Transport]]-
transport
-
stream을 반환한다.
11.
WebTransportWriter 인터페이스
WebTransportWriter
는 WritableStreamDefaultWriter
의 하위 클래스로,
두 가지 메서드가 추가됩니다.
WebTransportWriter
는 항상
생성
절차에 의해 생성됩니다.
[Exposed=*,SecureContext ]interface :WebTransportWriter WritableStreamDefaultWriter {Promise <undefined >atomicWrite (optional any );chunk undefined commit (); };
11.1. 메서드
atomicWrite(chunk)-
atomicWrite메서드는 전달된 chunk가 전송 시점의 흐름 제어 윈도우 내에서 전체가 전송될 수 없다면 거절됩니다. 이 동작은 흐름 제어 교착 상태에 민감한 특수 트랜잭션 기반 응용을 만족시키기 위해 설계되었습니다 ([RFC9308] Section 4.4 참고).참고:
atomicWrite는 일부 데이터를 전송한 후에도 거절될 수 있습니다. 흐름 제어 관점에서만 원자성을 제공하며, 다른 오류가 발생할 수 있습니다.atomicWrite는 데이터가 패킷 사이에서 분할되거나 다른 데이터와 interleaved되는 것을 방지하지 않습니다. 단지 송신자만atomicWrite가 흐름 제어 크레딧 부족으로 실패한 것을 알 수 있습니다.참고: 원자적 쓰기는 비원자적 쓰기 뒤에 큐에 있을 경우 여전히 블록될 수 있습니다. 만약 원자적 쓰기가 거절되면, 그 시점 이후 큐에 있는 모든 요청도 거절됩니다. 이렇게 거절된 비원자적 쓰기는 스트림 에러를 발생시킵니다. 따라서 응용에서는 항상 atomicWrite를 await하는 것이 권장됩니다.
atomicWrite가 호출되면, 유저 에이전트는 다음 단계를 실행해야 합니다:-
p를
write(chunk)를WritableStreamDefaultWriter에 chunk를 사용해 호출한 결과로 둡니다. -
Append p를 stream.
[[AtomicWriteRequests]]에 추가합니다. -
promise가 settle 될 때 반응하는 결과를 반환하며, 다음 단계를 실행합니다:
-
stream.
[[AtomicWriteRequests]]가 p를 포함하면, p를 제거합니다. -
p가 r 이유로 거절되면, 거절된 promise를 r로 반환합니다.
-
undefined를 반환합니다.
-
-
commit()-
commit메서드는 스트림의[[CommittedOffset]]값을 해당 스트림에 기록된 바이트 수([[BytesWritten]])로 갱신합니다. 이렇게 하면 쓰기가 중단(abort)되어 스트림이 송신 중단(abort sending)되더라도 해당 바이트가 피어에게 신뢰성 있게 전달됨을 보장합니다. 이 동작은 [RELIABLE-RESET]에서 설명된 메커니즘을 사용합니다.참고: 이 메서드는 연결이 실패한 경우에는 전달을 보장하지 않으며, 스트림이 송신 중단(abort sending)된 경우에만 전달이 보장됩니다.
commit이 stream에 대해 호출되면, 유저 에이전트는 다음 단계를 실행해야 합니다:-
transport를 stream.
[[Transport]]로 둡니다. -
stream.
[[CommittedOffset]]를 stream.[[BytesWritten]]값으로 설정합니다.
-
11.2. 절차
create를 수행하여
WebTransportWriter를
만들고,
WebTransportSendStream
stream이 주어졌을 때 다음 단계를 실행한다:
-
writer를 new로 생성한
WebTransportWriter로 둔다. -
new WritableStreamDefaultWriter(stream) 생성자 단계를 실행하되 writer를 this로, 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, 읽기 전용, null 허용-
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 효과 |
|---|---|
| 세션 drained | 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
기준. [RELIABLE-RESET] 참고
|
writable.close()
| STREAM 송신(streams) - FIN 비트 설정됨 |
writable.getWriter().write(chunk)()
| STREAM 송신(streams) |
writable.getWriter().close()
| STREAM 송신(streams) - FIN 비트 설정됨 |
writable.getWriter().abort(error)
| STREAM 송신 중단(aborts sending) - httpErrorCode와
[[CommittedOffset]]
오프셋, 그리고 스트림 헤더 포함; stream
기준. [RELIABLE-RESET] 참고
|
readable.cancel(error)
| STREAM 수신 중단(aborts receiving) - httpErrorCode |
readable.getReader().cancel(error)
| STREAM 수신 중단(aborts receiving) - httpErrorCode |
wt.close(closeInfo)
| 세션
종료(terminate) - closeInfo |
| QUIC 프로토콜 동작 | API 효과 |
|---|---|
| received STOP_SENDING with httpErrorCode | errors writable
with streamErrorCode
|
| STREAM 수신(received) | (await
readable.getReader().read()).value
|
| STREAM 수신(received) - FIN 비트 설정됨 | (await
readable.getReader().read()).done
|
| received RESET_STREAM with httpErrorCode | errors readable
with streamErrorCode
|
| 세션 정상 종료(terminated) - closeInfo | (await wt.closed).closeInfo,
그리고
errors 열린 스트림들
|
| 네트워크 오류 | (await wt.closed)
reject됨, 그리고
errors 열린 스트림들
|
참고: [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 효과 |
|---|---|
| 세션 drained | await wt.draining
|
만약 기본 연결이 HTTP/2를 사용한다면 [WEB-TRANSPORT-HTTP2]의 다음 프로토콜 동작이 적용됩니다. HTTP/3과 달리, 스트림 에러 코드를 HTTP 에러 코드로 변환할 필요는 없습니다.
| API 메서드 | HTTP/2 프로토콜 동작 |
|---|---|
writable.abort(error)
| WT_STREAM 송신 중단(aborts sending) - error |
writable.close()
| WT_STREAM 송신(streams) - FIN 비트 설정됨 |
writable.getWriter().write()
| WT_STREAM 송신(streams) |
writable.getWriter().close()
| WT_STREAM 송신(streams) - FIN 비트 설정됨 |
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)
| 세션
종료(terminate) - closeInfo |
| HTTP/2 프로토콜 동작 | API 효과 |
|---|---|
| received WT_STOP_SENDING - error | errors writable
with streamErrorCode
|
| WT_STREAM 수신(received) | (await
readable.getReader().read()).value
|
| WT_STREAM 수신(received) - FIN 비트 설정됨 | (await
readable.getReader().read()).done
|
| received WT_RESET_STREAM - error | errors readable
with streamErrorCode
|
| 세션 정상 종료(terminated) - closeInfo | (await wt.closed).closeInfo,
그리고
errors 열린 스트림들
|
| 네트워크 오류 | (await wt.closed)
reject됨, 그리고
errors 열린 스트림들
|
| 세션 drained | 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에서 처음 기술되었습니다.
이 명세서에 맞게 적용되었습니다.