1. 소개
이 섹션은 규범적인 내용이 아닙니다.
이 명세는 [WEB-TRANSPORT-HTTP3] 및 [WEB-TRANSPORT-HTTP2]를 사용하여 서버와 데이터를 주고받습니다. WebSockets처럼 사용할 수 있지만, 여러 스트림, 단방향 스트림, 순서에 상관없는 전송, 신뢰성 있는 전송과 신뢰성이 없는 전송 모두를 지원합니다.
참고: 이 명세에서 제공하는 API는 IETF WEBTRANS WG에서 진행 중인 작업을 바탕으로 한 예비 제안입니다. [WEB-TRANSPORT-HTTP3] 및 [WEB-TRANSPORT-HTTP2] 명세가 진행 중이므로 프로토콜과 API 모두 앞으로 상당히 변경될 수 있습니다.
2. 준수
비규범적으로 표시된 섹션뿐만 아니라, 이 명세의 모든 작성 지침, 도표, 예시, 참고 사항은 규범적인 내용이 아닙니다. 그 외의 모든 내용은 규범적입니다.
이 명세에서 "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", "OPTIONAL"이라는 핵심 용어는 [RFC2119] 및 [RFC8174]에서 설명된 대로, 오직 대문자로 나타날 때만 해당 의미로 해석됩니다.
이 명세는 하나의 제품에 적용되는 준수 기준을 정의합니다: 이 명세에 포함된 인터페이스를 구현하는 사용자 에이전트입니다.
알고리즘이나 특정 단계로 표현된 준수 요구사항은 최종 결과가 동일하기만 하면 어떤 방식으로 구현해도 됩니다. (특히, 이 명세에서 정의된 알고리즘은 따라가기 쉽도록 설계된 것이며, 성능을 위한 것이 아닙니다.)
이 명세에서 정의된 API를 ECMAScript로 구현하는 경우, 반드시 Web IDL 명세 [WEBIDL]에 정의된 ECMAScript 바인딩과 용어에 따라 일관되게 구현해야 합니다. 이 명세는 해당 명세와 용어를 사용합니다.
3. 프로토콜 개념
WebTransport에는 두 가지 주요 프로토콜 개념이 있습니다: 세션과 스트림. 각 WebTransport 세션은 여러 개의 WebTransport 스트림을 포함할 수 있습니다.
이들은 프로토콜 이름과 혼동해서는 안 되며, 이는 애플리케이션 수준의 API 구조입니다.
3.1. WebTransport 세션
WebTransport 세션은 HTTP/3 또는 HTTP/2 하위 연결에서의 WebTransport 세션입니다. 풀링이 활성화되면 하나의 연결에 여러 WebTransport 세션이 있을 수 있습니다.
WebTransport 세션은 [WEB-TRANSPORT-OVERVIEW]에 정의된 다음 기능을 가집니다:
WebTransport 세션을 origin origin과 protocols 배열로 설정하려면, [WEB-TRANSPORT-OVERVIEW]
섹션
4.1을 따르며,
origin을 직렬화 및 동형 인코딩해서 요청의
`Origin
`
헤더로 사용합니다.
동형 인코딩된 protocols는 클라이언트가 세션에서 서버가 사용하길 원하는 프로토콜 목록(우선
순위대로)으로, [WEB-TRANSPORT-OVERVIEW]
섹션 3.1을
따릅니다.
세션을 설정할 때, 클라이언트는 어떤 인증 정보도 제공해서는 안 됩니다.
결과 하위 트랜스포트 스트림은 세션의 CONNECT
스트림이라 부릅니다.
WebTransport 세션 session을 드레인하려면 [WEB-TRANSPORT-OVERVIEW] 섹션 4.1을 따릅니다.
WebTransport 세션 session이 드레인 중일 때는, CONNECT 스트림이 서버에 의해 정상적으로 닫히도록 요청된 경우를 의미하며, [WEB-TRANSPORT-OVERVIEW] 섹션 4.1에 설명되어 있습니다.
WebTransport 세션 session을 선택적 정수 code 및 선택적 바이트 시퀀스 reason과 함께 종료하려면 [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 | 예 | 아니오 | 예 |
STOP_SENDING 전송 | [WEB-TRANSPORT-OVERVIEW] 섹션 4.3 | 예 | 아니오 | 예 |
WebTransport 스트림 리셋 | [WEB-TRANSPORT-OVERVIEW] 섹션 4.3 | 아니오 | 예 | 예 |
WebTransport 스트림은 다음과 같은 신호를 가집니다:
이벤트 | 정의 | 단방향(수신) | 단방향(송신) | 양방향 |
---|---|---|---|---|
STOP_SENDING | [WEB-TRANSPORT-OVERVIEW] 섹션 4.3 | 아니오 | 예 | 예 |
RESET_STREAM | [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]]
| 송신 데이터그램, 타임스탬프, 데이터그램이 전송 또는 폐기될 때 해결되는 프로미스의 튜플 큐입니다. |
[[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
객체는 다음 내부 슬롯을 가집니다.
내부 슬롯 | 설명 (비규범적) |
---|---|
[[Readable]]
| 수신 데이터그램을 위한 ReadableStream .
|
[[Writables]]
| 순서가 있는 집합의 WebTransportDatagramsWritable
스트림.
처음에는 비어 있음.
|
[[IncomingDatagramsQueue]]
| 수신 데이터그램과 타임스탬프의 쌍으로 이루어진 큐. |
[[IncomingDatagramsPullPromise]]
| pullDatagrams에 의해 설정되며, 수신 데이터그램을 기다리는 프로미스. |
[[IncomingDatagramsHighWaterMark]]
|
수신 데이터그램의 하이 워터마크를 나타내는 unrestricted double
값.
|
[[IncomingDatagramsExpirationDuration]]
| 수신 데이터그램의 만료 기간(밀리초)을 나타내는 unrestricted double
값 또는 null.
|
[[OutgoingDatagramsHighWaterMark]]
|
송신 데이터그램의 하이 워터마크를 나타내는 unrestricted double
값.
|
[[OutgoingDatagramsExpirationDuration]]
| 송신 데이터그램의 만료 기간(밀리초)을 나타내는 unrestricted double
값 또는 null.
|
[[OutgoingMaxDatagramSize]]
|
송신 데이터그램의 최대 크기를 나타내는 정수 값.
최대 데이터그램 크기는 사용 중인 프로토콜에 따라 다릅니다.
HTTP/3 [WEB-TRANSPORT-HTTP3]에서는 경로 MTU
추정치와 관련 있으며, 오버헤드를 감안해 구현 정의 값만큼 줄어듭니다.
HTTP/2 [WEB-TRANSPORT-HTTP2]에서는 해당 제한이 없습니다.
데이터그램 처리에는 전체 데이터그램을 메모리에 보관하는 과정이 포함되므로, 구현에는 크기 제한이 있을 수 있습니다. 향후 프로토콜 확장으로 모든 프로토콜 변형에 대해 이러한 크기 제한을 신호할 수 있을 것입니다. |
사용자 에이전트는 [[OutgoingMaxDatagramSize]]
값을 WebTransport
객체 중
[[State]]
가
"connecting"
또는 "connected"
인 경우에 업데이트할 수 있습니다.
생성하려면,
WebTransportDatagramDuplexStream
을
readable로 다음 절차를
수행합니다.
-
stream을 new
WebTransportDatagramDuplexStream
으로 생성하며, 다음을 포함합니다:[[Readable]]
-
readable
[[Writables]]
-
비어 있는 순서가 있는 집합
[[IncomingDatagramsQueue]]
-
빈 큐
[[IncomingDatagramsPullPromise]]
-
null
[[IncomingDatagramsHighWaterMark]]
[[IncomingDatagramsExpirationDuration]]
-
null
[[OutgoingDatagramsHighWaterMark]]
-
이 구현 정의 값은 전송 데이터의 적절한 처리량을 보장하면서도 시의성(timeliness)을 해치지 않도록 조정되어야 합니다.
[[OutgoingDatagramsExpirationDuration]]
-
null
[[OutgoingMaxDatagramSize]]
-
stream을 반환합니다.
5.2. 메서드
createWritable()
-
WebTransportDatagramsWritable
를 생성합니다.createWritable()
메서드가 호출되면, 사용자 에이전트는 다음 절차를 실행해야 합니다:-
transport를 this와 연관된
WebTransport
객체로 설정합니다. -
transport.
[[State]]
가"closed"
또는"failed"
라면, InvalidStateError 예외를 throw합니다. -
생성된
WebTransportDatagramsWritable
을 transport, sendGroup, sendOrder로 반환합니다.
-
5.3. 속성
readable
, 타입 ReadableStream, 읽기 전용-
getter 단계:
-
this의
[[Readable]]
을 반환합니다.
-
incomingMaxAge
, 타입 unrestricted double, nullable-
getter 단계:
setter 단계 (값 value 주어짐):
-
value가 음수 또는 NaN이면, RangeError 예외를 throw합니다.
-
value가
0
이면, value를 null로 설정합니다. -
this의
[[IncomingDatagramsExpirationDuration]]
을 value로 설정합니다.
maxDatagramSize
, 타입 unsigned long, 읽기 전용-
WebTransportDatagramsWritable
에 전달될 수 있는 최대 데이터 크기입니다. getter 단계는 this의[[OutgoingMaxDatagramSize]]
을 반환합니다. outgoingMaxAge
, 타입 unrestricted double, nullable-
getter 단계:
setter 단계 (값 value 주어짐):
-
value가 음수 또는 NaN이면, RangeError 예외를 throw합니다.
-
value가
0
이면, value를 null로 설정합니다. -
this의
[[OutgoingDatagramsExpirationDuration]]
을 value로 설정합니다.
incomingHighWaterMark
, 타입 unrestricted double-
getter 단계:
-
this의
[[IncomingDatagramsHighWaterMark]]
을 반환합니다.
setter 단계 (값 value 주어짐):
-
value가 음수 또는 NaN이면, RangeError 예외를 throw합니다.
-
value가
1
보다 작으면, value를1
로 설정합니다. -
this의
[[IncomingDatagramsHighWaterMark]]
을 value로 설정합니다.
-
outgoingHighWaterMark
, 타입 unrestricted double-
getter 단계:
-
this의
[[OutgoingDatagramsHighWaterMark]]
을 반환합니다.
setter 단계 (값 value 주어짐):
-
value가 음수 또는 NaN이면, RangeError 예외를 throw합니다.
-
value가
1
보다 작으면, value를1
로 설정합니다. -
this의
[[OutgoingDatagramsHighWaterMark]]
을 value로 설정합니다.
-
5.4. 절차
pullDatagrams를 수행하려면,
WebTransport
객체 transport로 다음 절차를 실행합니다:
-
datagrams를 transport.
[[Datagrams]]
로 설정합니다. -
단언: datagrams.
[[IncomingDatagramsPullPromise]]
가 null임을 보장합니다. -
queue를 datagrams.
[[IncomingDatagramsQueue]]
로 설정합니다. -
queue가 비어 있으면:
-
datagrams.
[[IncomingDatagramsPullPromise]]
에 새 프로미스를 설정합니다. -
datagrams.
[[IncomingDatagramsPullPromise]]
를 반환합니다.
-
-
datagram과 timestamp를 queue에서 dequeue한 결과로 설정합니다.
-
datagrams.
[[Readable]]
의 현재 BYOB 요청 view가 null이 아니면:-
view를 datagrams.
[[Readable]]
의 현재 BYOB 요청 view로 설정합니다. -
view의 byte length가 datagram의 크기보다 작으면, RangeError로 거부된 프로미스를 반환합니다.
-
elementSize를 Typed array constructors table에서 view.[[TypedArrayName]]에 지정된 요소 크기로 설정합니다. view에 [[TypedArrayName]] 내부 슬롯이 없으면(
DataView
인 경우), elementSize를 0으로 설정합니다. -
elementSize가 1이 아니면, TypeError로 거부된 프로미스를 반환합니다.
-
-
바이트로부터 풀 datagram을 datagrams.
[[Readable]]
에 넣습니다. -
undefined로 resolve된 프로미스를 반환합니다.
receiveDatagrams를
수행하려면,
WebTransport
객체 transport로 다음 절차를 실행합니다:
-
timestamp를 현재 시점을 나타내는 타임스탬프로 설정합니다.
-
queue를 datagrams.
[[IncomingDatagramsQueue]]
로 설정합니다. -
duration을 datagrams.
[[IncomingDatagramsExpirationDuration]]
로 설정합니다. -
duration이 null이면, 구현 정의 값으로 설정합니다.
-
session을 transport.
[[Session]]
로 설정합니다. -
session에서 수신 가능한 데이터그램이 존재하는 동안:
-
toBeRemoved를 queue의 길이에서 datagrams.
[[IncomingDatagramsHighWaterMark]]
를 뺀 값으로 설정합니다. -
toBeRemoved가 양수이면, 큐에서 dequeue를 queue에 대해 toBeRemoved번(내림) 반복합니다.
-
queue가 비어 있지 않은 동안:
-
bytes와 timestamp를 queue의 첫 번째 요소로 설정합니다.
-
timestamp로부터 duration 밀리초 이상 경과했다면 queue에서 dequeue를 queue에 대해 실행합니다.
-
그렇지 않으면 이 루프를 종료합니다.
-
-
queue가 비어 있지 않고 datagrams.
[[IncomingDatagramsPullPromise]]
가 null이 아니면:-
bytes와 timestamp를 queue에서 dequeue한 결과로 설정합니다.
-
promise를 datagrams.
[[IncomingDatagramsPullPromise]]
로 설정합니다. -
datagrams.
[[IncomingDatagramsPullPromise]]
를 null로 설정합니다. -
네트워크 작업을 큐에 추가하여 transport로 다음 절차를 실행합니다:
-
chunk를
Uint8Array
객체로, bytes를 나타내는 것으로 생성합니다. -
chunk를 enqueue datagrams.
[[Readable]]
에 넣습니다.
-
-
사용자 에이전트는 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 <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 세션이 설정되면 fulfilled되고, 설정 과정이 실패하면 rejected되는 프로미스. |
[[Reliability]]
| WebTransportReliabilityMode 로,
첫 홉이 비신뢰성(UDP) 전송을 지원하는지, 또는 신뢰성(TCP 폴백) 전송만 가능한지를 나타냄. 연결이 설정될 때까지 "pending" 반환.
|
[[CongestionControl]]
| WebTransportCongestionControl 로,
애플리케이션이 처리량 또는 저지연에 최적화된 혼잡 제어 알고리즘의 선호도를 요청했고 사용자 에이전트가 이를 만족시켰는지, 아니면
"default" 인지를 나타냄.
|
[[AnticipatedConcurrentIncomingUnidirectionalStreams]]
| 애플리케이션이 서버에서 생성할 것으로 예상하는 동시에 열린 단방향(수신) 스트림의 개수 또는 null. |
[[AnticipatedConcurrentIncomingBidirectionalStreams]]
| 애플리케이션이 서버에서 생성할 것으로 예상하는 동시에 열린 양방향 스트림의 개수 또는 null. |
[[Protocol]]
| 서버에서 선택한 애플리케이션 수준 프로토콜을 나타내는 문자열. 초깃값은 빈 문자열. |
[[Closed]]
| 관련 WebTransport
객체가 정상적으로 종료되면 fulfilled, 비정상적으로 종료되거나 초기화에 실패하면 rejected되는 프로미스.
|
[[Draining]]
| 관련 WebTransport 세션이 드레인됨 경우 fulfilled되는 프로미스. |
[[Datagrams]]
| WebTransportDatagramDuplexStream .
|
[[Session]]
| 이 WebTransport
객체에 대한 WebTransport 세션 또는 null.
|
6.2. 생성자
WebTransport()
생성자가 호출되면, 사용자 에이전트는 다음 단계를 실행해야 합니다:
-
baseURL을 this의 relevant settings object의 API base URL로 설정합니다.
-
parsedURL을 URL record로, parsing
url
과 baseURL을 이용하여 생성합니다. -
parsedURL이 실패라면, SyntaxError 예외를 throw합니다.
-
parsedURL의 scheme이
https
가 아니면, SyntaxError 예외를 throw합니다. -
parsedURL의 fragment가 null이 아니면, SyntaxError 예외를 throw합니다.
-
allowPooling을
options
의allowPooling
값으로 설정합니다. -
dedicated를 allowPooling의 부정으로 설정합니다.
-
serverCertificateHashes를
options
의serverCertificateHashes
값이 있다면 그 값으로, 없으면 null로 설정합니다. -
dedicated가 false이고 serverCertificateHashes가 null이 아니면 NotSupportedError 예외를 throw합니다.
-
requireUnreliable을
options
의requireUnreliable
값으로 설정합니다. -
congestionControl을
options
의congestionControl
값으로 설정합니다. -
congestionControl이
"default"
가 아니면서 사용자 에이전트가 [RFC9002] Section 7에 따라 congestionControl에 최적화된 혼잡 제어 알고리즘을 지원하지 않으면, congestionControl을"default"
로 설정합니다. -
protocols 값 중 중복이 존재하거나, WebTransport 프로토콜에 정의된 협상된 애플리케이션 프로토콜 값 요건을 충족하지 못하거나, isomorphic encoded 길이가 0이거나 512를 초과하면, SyntaxError 예외를 throw합니다. [WEB-TRANSPORT-OVERVIEW] Section 3.1.
-
anticipatedConcurrentIncomingUnidirectionalStreams를
options
의anticipatedConcurrentIncomingUnidirectionalStreams
값으로 설정합니다. -
anticipatedConcurrentIncomingBidirectionalStreams를
options
의anticipatedConcurrentIncomingBidirectionalStreams
값으로 설정합니다. -
incomingDatagrams을 new
ReadableStream
으로 생성합니다. -
datagrams을 WebTransportDatagramDuplexStream 생성 결과로, readable은 incomingDatagrams로 설정합니다.
-
transport을 새롭게 생성한
WebTransport
객체로, 다음과 같이 설정합니다:[[SendStreams]]
-
비어 있는 순서가 있는 집합
[[ReceiveStreams]]
-
비어 있는 순서가 있는 집합
[[IncomingBidirectionalStreams]]
[[IncomingUnidirectionalStreams]]
[[State]]
-
"connecting"
[[Ready]]
-
새 프로미스
[[Reliability]]
-
"pending"
[[CongestionControl]]
-
congestionControl
[[AnticipatedConcurrentIncomingUnidirectionalStreams]]
-
anticipatedConcurrentIncomingUnidirectionalStreams
[[AnticipatedConcurrentIncomingBidirectionalStreams]]
-
anticipatedConcurrentIncomingBidirectionalStreams
[[Protocol]]
-
빈 문자열
[[Closed]]
-
새 프로미스
[[Draining]]
-
새 프로미스
[[Datagrams]]
-
datagrams
[[Session]]
-
null
-
pullDatagramsAlgorithm을 pullDatagrams를 transport로 실행하는 동작으로 정의합니다.
참고: 데이터그램에 64kB 버퍼를 사용하는 것이 권장됩니다. WebTransport 데이터그램 프레임의 최대 크기는 QUIC 데이터그램 프레임의 최대 크기(권장값 64kB)를 상한으로 하므로 ([QUIC-DATAGRAM] Section 3 참조), 버퍼보다 큰 데이터그램으로 스트림이 에러되는 것을 방지할 수 있습니다.
-
Set up with byte reading support 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으로 설정합니다. -
WebTransport over HTTP 초기화를 transport, parsedURL, dedicated, requireUnreliable, congestionControl, protocols, serverCertificateHashes로 실행합니다.
-
transport를 반환합니다.
WebTransport
객체
transport, URL record url, 불리언 dedicated, 불리언
requireUnreliable, WebTransportCongestionControl
congestionControl,
protocols 배열, 그리고
sequence<WebTransportHash
>
serverCertificateHashes로 다음 절차를 실행합니다.
-
client를 transport의 관련 설정 객체로 설정합니다.
-
origin을 client의 origin으로 설정합니다.
-
request를 새 request로, URL은 url, client는 client, policy container는 client의 policy container, destination은 빈 문자열, origin은 origin, redirect mode는 "error"로 설정합니다.
-
Content Security Policy 위반 보고를 request에 대해 실행합니다.
-
Content Security Policy에 의해 요청이 차단되어야 하는지를 request로 검사하여 "Blocked"를 반환하거나, request가 잘못된 포트로 인해 차단되어야 하는지 검사하여 blocked를 반환하면, 남은 절차를 중단하고 네트워크 작업 큐에 추가하여 transport로 다음 절차를 실행합니다:
-
transport.
[[State]]
값이"closed"
또는"failed"
이면 절차를 중단합니다. -
error를 생성한
WebTransportError
로,source
값은"session"
으로 설정합니다. -
Cleanup transport와 error를 실행합니다.
-
-
networkPartitionKey를 네트워크 파티션 키 결정 결과로, transport의 관련 설정 객체로 실행합니다.
-
다음 단계를 병렬로 실행하되, 아래의 경우 중단: transport.
[[State]]
값이"closed"
또는"failed"
가 되는 경우:-
newConnection을 dedicated이 false면 "
no
", 아니면 "yes-and-dedicated
"로 설정합니다. -
connection을 연결 획득 결과로, networkPartitionKey, url, false, newConnection, requireUnreliable로 실행합니다. 사용자 에이전트가 둘 이상의 혼잡 제어 알고리즘을 지원한다면, congestionControl에 적합한 알고리즘을 선택하여 connection에서 데이터 전송에 사용합니다. 연결 획득 시 serverCertificateHashes가 지정되면, 기본 인증서 검증 알고리즘 대신 사용자 지정 인증서 요구사항을 만족하고, 인증서 해시 검증 결과가 true면 인증서를 유효로 간주합니다. 둘 중 하나라도 만족하지 않으면 connection을 failure로 설정합니다.
-
connection이 failure인 경우, 남은 절차를 중단하고 네트워크 작업 큐에 추가하여 transport로 다음을 실행합니다:
-
transport.
[[State]]
값이"closed"
또는"failed"
이면 절차를 중단합니다. -
error를 생성한
WebTransportError
로,source
값은"session"
으로 설정합니다. -
Cleanup transport와 error를 실행합니다.
참고: 리다이렉트는 따르지 않습니다. 리다이렉트로 인한 네트워크 오류는 의도적으로 다른 네트워크 오류와 구별되지 않습니다. 교차 출처 컨텍스트에서는 CORS로 차단되는 정보를 노출할 수 있기 때문입니다. 동일 출처 컨텍스트에서는 핸드셰이크를 정보 전달 벡터로 악용할 수 있습니다.
-
-
connection이 SETTINGS 프레임을 처음 받을 때까지 대기하고, settings를 그 SETTINGS 프레임을 나타내는 딕셔너리로 설정합니다.
-
settings에 SETTINGS_ENABLE_WEBTRANPORT 값이 1인 항목이나 H3_DATAGRAM 값이 1인 항목이 없으면 남은 절차를 중단하고 네트워크 작업 큐에 추가하여 transport로 다음을 실행합니다:
-
transport.
[[State]]
값이"closed"
또는"failed"
이면 절차를 중단합니다. -
error를 생성한
WebTransportError
로,source
값은"session"
으로 설정합니다. -
Cleanup transport와 error를 실행합니다.
-
-
WebTransport 세션 설정을 origin, protocols, connection으로 실행합니다.
참고: 이 단계에서 [QUIC-DATAGRAM]에서 지정한 트랜스포트 파라미터 교환도 포함됩니다.
-
이전 단계가 실패하면 남은 절차를 중단하고 네트워크 작업 큐에 추가하여 transport로 다음을 실행합니다:
-
transport.
[[State]]
값이"closed"
또는"failed"
이면 절차를 중단합니다. -
error를 생성한
WebTransportError
로,source
값은"session"
으로 설정합니다. -
Cleanup transport와 error를 실행합니다.
-
-
session을 설정된 WebTransport 세션으로 설정합니다.
-
단언: maxDatagramSize는 정수입니다.
-
네트워크 작업 큐에 추가하여 transport로 다음 절차를 실행합니다:
-
transport.
[[State]]
값이"connecting"
이 아니면:-
병렬로 session 종료를 session으로 실행합니다.
-
절차를 중단합니다.
-
-
transport.
[[State]]
값을"connected"
로 설정합니다. -
transport.
[[Session]]
값을 session으로 설정합니다. -
transport.
[[Protocol]]
값을 협상된 애플리케이션 프로토콜의 문자열 값(존재하면)으로 설정하거나, [WEB-TRANSPORT-OVERVIEW] Section 3.1 절차에 따릅니다. 없다면""
로 설정합니다. -
연결이 HTTP/3 연결이면, transport.
[[Reliability]]
값을"supports-unreliable"
로 설정합니다. -
연결이 HTTP/2 연결이면 [WEB-TRANSPORT-HTTP2], transport의
[[Reliability]]
값을"reliable-only"
로 설정합니다.
-
-
WebTransport
객체 transport로 다음 단계를 실행합니다.
-
transport.
[[State]]
값이"connecting"
이면, transport.[[Ready]]
가 이행될 때 다음 단계를 실행한 결과를 반환합니다:-
pullBidirectionalStream을 transport로 실행한 결과를 반환합니다.
-
-
transport.
[[State]]
값이"connected"
가 아니면, Rejected 프로미스와InvalidStateError
를 반환합니다. -
session을 transport.
[[Session]]
로 설정합니다. -
p를 새 프로미스로 설정합니다.
-
다음 단계를 병렬로 실행합니다:
-
수신 가능한 양방향 스트림이 있을 때까지 대기합니다.
-
internalStream을 양방향 스트림 수신 결과로 설정합니다.
-
네트워크 작업 큐에 추가하여 transport로 다음을 실행합니다:
-
stream을 WebTransportBidirectionalStream 생성 결과로, internalStream과 transport를 인자로 설정합니다.
-
stream을 enqueue하여 transport.
[[IncomingBidirectionalStreams]]
에 넣습니다.
-
-
-
p를 반환합니다.
WebTransport
객체 transport로 다음 단계를 실행합니다.
-
transport.
[[State]]
값이"connecting"
이면, transport.[[Ready]]
가 이행될 때 다음 단계를 실행한 결과를 반환합니다:-
pullUnidirectionalStream을 transport로 실행한 결과를 반환합니다.
-
-
transport.
[[State]]
값이"connected"
가 아니면, Rejected 프로미스와InvalidStateError
를 반환합니다. -
session을 transport.
[[Session]]
로 설정합니다. -
p를 새 프로미스로 설정합니다.
-
다음 단계를 병렬로 실행합니다:
-
수신 가능한 단방향 스트림이 있을 때까지 대기합니다.
-
internalStream을 단방향 스트림 수신 결과로 설정합니다.
-
네트워크 작업 큐에 추가하여 transport로 다음을 실행합니다:
-
stream을 WebTransportReceiveStream 생성 결과로, internalStream과 transport를 인자로 설정합니다.
-
stream을 enqueue하여 transport.
[[IncomingUnidirectionalStreams]]
에 넣습니다.
-
-
-
p를 반환합니다.
6.3. 속성
ready
, 타입 Promise<undefined>, 읽기 전용closed
, 타입 Promise<WebTransportCloseInfo>, 읽기 전용-
getter 시 this의
[[Closed]]
를 반환해야 합니다. draining
, 타입 Promise<undefined>, 읽기 전용-
getter 시 this의
[[Draining]]
를 반환해야 합니다. datagrams
, 타입 WebTransportDatagramDuplexStream, 읽기 전용-
이 세션에서 데이터그램 송수신을 위한 단일 이중 스트림.
datagrams
속성의 getter 단계는 다음과 같습니다:-
this의
[[Datagrams]]
를 반환합니다.
-
incomingBidirectionalStreams
, 타입 ReadableStream, 읽기 전용-
서버로부터 수신된
WebTransportBidirectionalStream
객체의ReadableStream
을 반환합니다.참고: 스트림에 이미 데이터가 있는지 여부는 서버 동작에 따라 다릅니다.
incomingBidirectionalStreams
속성의 getter 단계는 다음과 같습니다:-
this의
[[IncomingBidirectionalStreams]]
를 반환합니다.
-
incomingUnidirectionalStreams
, 타입 ReadableStream, 읽기 전용-
서버로부터 수신된 단방향 스트림 각각을
WebTransportReceiveStream
으로 나타내는ReadableStream
을 반환합니다.참고: 스트림에 이미 데이터가 있는지 여부는 서버 동작에 따라 다릅니다.
incomingUnidirectionalStreams
의 getter 단계는 다음과 같습니다: reliability
, 타입 WebTransportReliabilityMode, 읽기 전용-
연결이 UDP 기반 비신뢰성 전송을 지원하는지, 혹은 TCP 폴백 신뢰성 전송만 지원하는지를 나타냅니다. 연결이 설정될 때까지는
"pending"
을 반환합니다. getter 단계는 this의[[Reliability]]
를 반환합니다. congestionControl
, 타입 WebTransportCongestionControl, 읽기 전용-
애플리케이션이 생성자에서 요청한 경우, 그리고 사용자 에이전트가 이를 만족시킨 경우, 이 연결에서 송신에 대해 처리량 또는 저지연에 최적화된 혼잡 제어 알고리즘을 사용할 선호도입니다. 선호도가 요청되었으나 만족되지 않으면 값은
"default"
입니다. getter 단계는 this의[[CongestionControl]]
를 반환합니다. supportsReliableOnly
, 타입 boolean, 읽기 전용-
사용자 에이전트가 WebTransport 세션을 오직 신뢰성 연결 위에서만 지원하는 경우 true, 그렇지 않으면 false를 반환합니다.
anticipatedConcurrentIncomingUnidirectionalStreams
, 타입 unsigned short, nullable-
애플리케이션이 서버가 동시에 생성할 것으로 예상하는 수신 단방향 스트림 개수를 지정할 수 있습니다. null이 아니면 사용자 에이전트는 이후 왕복(RTT)을 줄이기 위해
[[AnticipatedConcurrentIncomingUnidirectionalStreams]]
값을 서버와 협상 시 고려해야 합니다.getter 단계는 this의
[[AnticipatedConcurrentIncomingUnidirectionalStreams]]
를 반환합니다.setter 단계에서 value가 주어지면 this의
[[AnticipatedConcurrentIncomingUnidirectionalStreams]]
를 value로 설정합니다. anticipatedConcurrentIncomingBidirectionalStreams
, 타입 unsigned short, nullable-
애플리케이션이 서버가 동시에 생성할 것으로 예상하는 양방향 스트림 개수를 지정할 수 있습니다. null이 아니면 사용자 에이전트는 이후 왕복(RTT)을 줄이기 위해
[[AnticipatedConcurrentIncomingBidirectionalStreams]]
값을 서버와 협상 시 고려해야 합니다.getter 단계는 this의
[[AnticipatedConcurrentIncomingBidirectionalStreams]]
를 반환합니다.setter 단계에서 value가 주어지면 this의
[[AnticipatedConcurrentIncomingBidirectionalStreams]]
를 value로 설정합니다.
참고: anticipatedConcurrentIncomingUnidirectionalStreams
또는
anticipatedConcurrentIncomingBidirectionalStreams
를
설정하더라도,
애플리케이션이 예상한 만큼의 스트림을 반드시 수신할 것이라는 보장은 없습니다.
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을 closeInfo.
reason
의 최대 코드 유닛 접두사로, 길이가 UTF-8 인코딩된 접두사가 1024를 넘지 않는 경우로 설정합니다. -
reason을 reasonString의 UTF-8 인코딩 값으로 설정합니다.
-
병렬로, session 종료를 session, code, reason으로 실행합니다.
참고: 이 단계는 또한 리셋 또는 STOP_SENDING 전송을 WebTransport 스트림에 대해 실행하며, transport.
[[SendStreams]]
및[[ReceiveStreams]]
에 포함된 스트림에 적용됩니다. -
Cleanup transport와
AbortError
, closeInfo를 실행합니다.
-
getStats()
-
이
WebTransport
의 기저 연결에 대한 통계를 수집하여 비동기로 결과를 반환합니다.getStats가 호출되면, 사용자 에이전트는 다음 단계를 실행해야 합니다:
-
transport를 this로 설정합니다.
-
p를 새 프로미스로 설정합니다.
-
transport.
[[State]]
값이"failed"
라면, p를 reject하고InvalidStateError
와 함께 이 절차를 중단합니다. -
다음 단계를 병렬로 실행합니다:
-
transport.
[[State]]
값이"connecting"
이면 변경될 때까지 대기합니다. -
transport.
[[State]]
값이"failed"
라면, 네트워크 작업 큐에 추가하여 transport로 p를 reject하고InvalidStateError
와 함께 절차를 중단합니다. -
transport.
[[State]]
값이"closed"
라면, 네트워크 작업 큐에 추가하여 transport로 p를 resolve하고, 연결에 대해 가장 최근 수집된 통계를 반환합니다. 해당 시점은 구현 정의입니다. -
기저 연결에서 통계를 수집하고, 데이터그램 통계도 포함합니다.
-
네트워크 작업 큐에 추가하여 transport로 다음을 실행합니다:
-
stats를 new
WebTransportConnectionStats
객체로, 수집한 통계를 나타냅니다. -
p를 resolve하고 stats를 반환합니다.
-
-
-
p를 반환합니다.
-
exportKeyingMaterial(BufferSource label, optional BufferSource context)
-
이
WebTransport
의 기저 연결에 고유하게 연결된 TLS 세션에 대해 TLS Keying Material Exporter에서 암호화 키 재료를 추출합니다.exportKeyingMaterial
이 호출되면, 사용자 에이전트는 다음 단계를 실행해야 합니다:-
transport를 this로 설정합니다.
-
labelLength를 label.바이트 길이로 설정합니다.
-
labelLength가 255를 초과하면 RangeError로 reject된 프로미스를 반환합니다.
-
contextLength를 0으로 설정합니다.
-
context가 주어진 경우, contextLength를 context.바이트 길이로 설정합니다.
-
contextLength가 255를 초과하면 RangeError로 reject된 프로미스를 반환합니다.
-
p를 새 프로미스로 설정합니다.
-
다음 단계를 병렬로 실행하지만, 다음 조건에서 중단: transport의
[[State]]
값이"closed"
또는"failed"
가 될 때, 대신 네트워크 작업 큐에 추가하여 transport로 p를 reject하고InvalidStateError
와 함께 중단합니다:-
keyingMaterial을 [WEB-TRANSPORT-HTTP3] Section 4.7에 따라 labelLength, label, contextLength, context(있으면)로 TLS 키 재료를 추출한 결과로 설정합니다.
-
네트워크 작업 큐에 추가하여 transport로 p를 resolve하고 keyingMaterial을 반환합니다.
-
-
p를 반환합니다.
-
createBidirectionalStream()
-
송신용 양방향 스트림을 위한
WebTransportBidirectionalStream
객체를 생성합니다. 스트림이 생성된 것만으로는 상대방에게 바로 보이지 않으며, 데이터가 전송될 때에야 상대방이 인지합니다.참고: 서버는 해당 스트림에 데이터가 전송되기 전까지 스트림의 존재를 인지할 필요가 없습니다.
createBidirectionalStream
이 호출되면, 사용자 에이전트는 다음 단계를 실행해야 합니다:-
transport를 this로 설정합니다.
-
transport.
[[State]]
값이"closed"
또는"failed"
라면, Rejected 프로미스와InvalidStateError
를 반환합니다. -
waitUntilAvailable를
options
의waitUntilAvailable
값으로 설정합니다. -
p를 새 프로미스로 설정합니다.
-
다음 단계를 병렬로 실행하지만, 아래 조건에서 중단: transport의
[[State]]
값이"closed"
또는"failed"
가 될 때, 대신 네트워크 작업 큐에 추가하여 transport로 p를 reject하고InvalidStateError
와 함께 중단합니다:-
streamId를 transport.
[[Session]]
에 대해 유효하고 고유한 새 스트림 ID로 설정합니다. ([QUIC] Section 19.11 참조) 바로 사용할 수 없을 경우, waitUntilAvailable가 true면 사용할 수 있을 때까지 대기, false면 네트워크 작업 큐에 추가하여 transport로 p를 reject하고,QuotaExceededError
와 함께 중단합니다. -
internalStream을 양방향 스트림 생성 결과로, transport.
[[Session]]
과 streamId를 인자로 설정합니다. -
네트워크 작업 큐에 추가하여 transport로 다음을 실행합니다:
-
transport.
[[State]]
값이"closed"
또는"failed"
라면, p를 reject하고InvalidStateError
와 함께 중단합니다. -
stream을 WebTransportBidirectionalStream 생성 결과로, internalStream, transport, sendGroup, sendOrder를 인자로 설정합니다.
-
p를 resolve하고 stream을 반환합니다.
-
-
-
p를 반환합니다.
-
createUnidirectionalStream()
-
송신용 단방향 스트림을 위한
WebTransportSendStream
을 생성합니다. 스트림 생성만으로는 서버에 바로 보이지 않으며, 데이터가 전송될 때에야 서버가 인지합니다.참고: 서버는 해당 스트림에 데이터가 전송되기 전까지 스트림의 존재를 인지할 필요가 없습니다.
createUnidirectionalStream()
가 호출되면, 사용자 에이전트는 다음 단계를 실행해야 합니다:-
transport를 this로 설정합니다.
-
transport.
[[State]]
값이"closed"
또는"failed"
라면, Rejected 프로미스와InvalidStateError
를 반환합니다. -
waitUntilAvailable를
options
의waitUntilAvailable
값으로 설정합니다. -
p를 새 프로미스로 설정합니다.
-
다음 단계를 병렬로 실행하지만, 아래 조건에서 중단: transport의
[[State]]
값이"closed"
또는"failed"
가 될 때, 대신 네트워크 작업 큐에 추가하여 transport로 p를 reject하고InvalidStateError
와 함께 중단합니다:-
streamId를 transport.
[[Session]]
에 대해 유효하고 고유한 새 스트림 ID로 설정합니다. ([QUIC] Section 19.11 참조) 바로 사용할 수 없을 경우, waitUntilAvailable가 true면 사용할 수 있을 때까지 대기, false면 네트워크 작업 큐에 추가하여 transport로 p를 reject하고,QuotaExceededError
와 함께 중단합니다. -
internalStream을 송신 단방향 스트림 생성 결과로, transport.
[[Session]]
과 streamId를 인자로 설정합니다. -
네트워크 작업 큐에 추가하여 transport로 다음을 실행합니다:
-
transport.
[[State]]
값이"closed"
또는"failed"
라면, p를 reject하고InvalidStateError
와 함께 중단합니다. -
stream을 WebTransportSendStream 생성 결과로, internalStream, transport, sendGroup, sendOrder를 인자로 설정합니다.
-
p를 resolve하고 stream을 반환합니다.
-
-
-
p를 반환합니다.
-
createSendGroup()
-
WebTransportSendGroup
를 생성합니다.createSendGroup()
가 호출되면, 사용자 에이전트는 다음 단계를 실행해야 합니다:-
transport를 this로 설정합니다.
-
transport.
[[State]]
값이"closed"
또는"failed"
라면, InvalidStateError 예외를 throw합니다. -
WebTransportSendGroup 생성 결과를 transport로 반환합니다.
-
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"
로 설정합니다. -
각 stream을 sendStreams에서 다음과 같이 처리합니다:
-
stream.
[[PendingOperation]]
이 null이 아니면, stream.[[PendingOperation]]
를 error로 reject합니다. -
에러 처리(error)를 stream에 error로 실행합니다.
-
-
각 stream을 receiveStreams에서 에러 처리(error)를 stream에 error로 실행합니다.
참고: 스크립트 작성자는 Promise 이행 시 동기적으로 코드를 삽입할 수 있으므로, 이후 transport를 예측 불가능하게 스크립트에 의해 변경될 수 있으니 접근하지 않습니다. 이 로직을 호출하는 부분에도 적용됩니다.
-
closeInfo가 주어지면:
-
그렇지 않으면:
-
reject closed에 error로 처리합니다.
-
closed.
[[PromiseIsHandled]]
를 true로 설정합니다. -
reject ready에 error로 처리합니다.
-
ready.
[[PromiseIsHandled]]
를 true로 설정합니다. -
에러 처리(error)를 incomingBidirectionalStreams에 error로 실행합니다.
-
에러 처리(error)를 incomingUnidirectionalStreams에 error로 실행합니다.
-
outgoingDatagramWritables의 각 writable에 에러 처리(error)를 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에 연결되어 있고
종료(terminated)될 때,
선택적으로 code 및 reasonBytes와 함께 다음 절차를 실행합니다:
-
네트워크 작업 큐에 추가를 transport로, 다음 단계를 실행합니다:
-
transport.
[[State]]
값이"closed"
또는"failed"
라면, 이 절차를 중단합니다. -
error를 생성한
WebTransportError
로,source
값을"session"
으로 설정합니다. -
closeInfo를 new
WebTransportCloseInfo
로 생성합니다. -
code가 주어졌다면, closeInfo의
closeCode
를 code로 설정합니다. -
reasonBytes가 주어졌다면, closeInfo의
reason
를 reasonBytes의 UTF-8 디코딩 값으로 설정합니다.참고: reasonBytes에는 언어 또는 방향 메타데이터가 없습니다. 값을 표시할 때 First-strong 휴리스틱을 사용할 수 있습니다.
-
정리(cleanup)를 transport와 error, closeInfo로 실행합니다.
-
WebTransport
transport의 기저 연결에서 연결 오류가 발생하면,
다음 절차를 실행합니다:
-
네트워크 작업 큐에 추가를 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"
로 설정합니다. -
병렬로, 세션 종료를 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
프로미스가 관찰되고 있다면 가비지 컬렉션되어서는 안 됩니다.
WebTransport
객체의 [[State]]
값이 "connected"
일 때,
[[IncomingBidirectionalStreams]]
,
[[IncomingUnidirectionalStreams]]
,
하나라도
WebTransportReceiveStream
,
또는 [[Datagrams]]
.[[Readable]]
가 locked 상태거나,
draining
또는 closed
프로미스가 관찰되고 있다면 가비지 컬렉션되어서는 안 됩니다.
WebTransport
객체의 [[State]]
값이 "draining"
일 때,
[[IncomingBidirectionalStreams]]
,
[[IncomingUnidirectionalStreams]]
,
하나라도
WebTransportReceiveStream
,
또는 [[Datagrams]]
.[[Readable]]
가 locked 상태거나,
closed
프로미스가 관찰되고 있다면 가비지 컬렉션되어서는 안 됩니다.
WebTransport 객체의 세션이 설정되어 있고 WebTransport 세션
에 네트워크로 전송될 대기 중인 데이터가 있다면(예: [[Datagrams]]
.[[OutgoingDatagramsQueue]]
의
데이터그램 포함),
가비지 컬렉션되어서는 안 됩니다.
WebTransport 객체가 가비지 컬렉션되는 동안 기저 연결
이 아직 열려 있으면, 사용자 에이전트는
WebTransport
세션 종료를
Application Error Code 0
및 Application Error Message ""
로 수행해야 합니다.
6.9. 구성(Configuration)
dictionary {
WebTransportHash DOMString ;
algorithm 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 = []; };enum {
WebTransportCongestionControl ,
"default" ,
"throughput" , };
"low-latency"
WebTransportOptions
는 WebTransport 세션이
어떻게 설정되고 사용되는지 결정하는 매개변수들의 딕셔너리입니다.
allowPooling
, 타입 boolean, 기본값false
-
true로 설정하면 WebTransport 세션이 풀링될 수 있습니다. 즉, 기저 연결이 다른 WebTransport 세션과 공유될 수 있습니다.
requireUnreliable
, 타입 boolean, 기본값false
-
true로 설정하면, HTTP/3 연결이 불가능한 경우 HTTP/2 연결을 통해서는 WebTransport 세션을 설정할 수 없습니다.
serverCertificateHashes
, 타입 sequence<WebTransportHash>-
이 옵션은 전용 연결을 사용하는 전송에만 지원됩니다. 이 기능을 지원하지 않는 전송 프로토콜에서 해당 필드가 비어 있지 않으면
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>, 기본값[]
-
애플리케이션 수준 프로토콜 이름 배열을 선택적으로 제공합니다. 서버는 선호하는 애플리케이션 프로토콜을 선택하여 클라이언트에 전달할 수 있습니다(선택적). 서버는 적절한 프로토콜이 제공되지 않으면 요청을 거부할 수도 있습니다.
-
cert를 certificate로, [RFC5280]에 정의된 Certificate 메시지의 DER 인코딩으로 표현합니다.
-
cert의 SHA-256 해시를 계산하여 그 값을 반환합니다.
-
referenceHash를 인증서 해시 계산을 certificate로 실행한 결과로 설정합니다.
-
각 hash를 hashes에서 다음과 같이 처리합니다:
-
hash.
value
값이 null이 아니고, hash.algorithm
값이 "sha-256"과 ASCII 대소문자 구분 없이 일치하면:-
hashValue를 hash.
value
가 나타내는 바이트 시퀀스로 설정합니다. -
hashValue가 referenceHash와 같으면 true를 반환합니다.
-
-
-
false를 반환합니다.
사용자 지정 인증서 요구사항은 다음과 같습니다: 인증서는 [RFC5280]에 정의된 X.509v3 인증서여야 하며, Subject Public Key 필드에 사용된 키는 허용된 공개키 알고리즘 중 하나여야 하며, 현재 시간은 [RFC5280] 4.1.2.5절에 정의된 인증서 유효기간 내에 있어야 하며, 전체 유효기간 길이는 2주를 넘지 않아야 합니다. 사용자 에이전트는 인증서에 추가 구현 정의 요구사항을 적용할 수 있습니다.
Subject Public Key Info 필드(그리고 TLS CertificateVerify 메시지에도)에서 사용할 허용된 공개키 알고리즘의 정확한 목록은 구현 정의입니다. 하지만, 상호 운용 가능한 기본값으로 secp256r1(NIST P-256) 그룹의 ECDSA는 반드시 포함되어야 합니다([RFC3279] 2.3.5절, [RFC8422]). RSA 키는 포함되어서는 안 됩니다([RFC3279] 2.3.1절).
6.10.
WebTransportCloseInfo
딕셔너리
WebTransportCloseInfo
딕셔너리는 WebTransport
의
종료 에러 코드와 관련된 정보를 포함합니다.
이 정보는 CONNECTION_CLOSE 프레임의 에러 코드와 이유(reason)를 지정하는 데 사용됩니다.
dictionary WebTransportCloseInfo {unsigned long closeCode = 0;USVString reason = ""; };
이 딕셔너리는 다음 속성을 가집니다:
closeCode
, 타입 unsigned long, 기본값0
-
피어로 전달되는 에러 코드입니다.
reason
, 타입 USVString, 기본값""
-
WebTransport
를 종료하는 이유(reason)입니다.
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 고유 통계 정보를
포함합니다.
참고: 풀링이 사용되는 경우, 동일한 WebTransport 세션이 동일한 연결에 풀링되어 있다면 모두 동일한 정보를 받습니다. 즉, 동일한 세션에 대해 네트워크 파티션 키가 같으면 정보가 공유됩니다.
참고: 제공되지 않는 통계 정보는 존재하지 않음(absent)으로 WebTransportConnectionStats
딕셔너리에 나타납니다.
dictionary WebTransportConnectionStats {unsigned long long bytesSent = 0;unsigned long long packetsSent = 0;unsigned long long bytesLost = 0;unsigned long long packetsLost = 0;unsigned long long bytesReceived = 0;unsigned long long packetsReceived = 0;required DOMHighResTimeStamp smoothedRtt ;required DOMHighResTimeStamp rttVariation ;required DOMHighResTimeStamp minRtt ;required WebTransportDatagramStats ;
datagrams unsigned long long ?estimatedSendRate =null ;boolean atSendCapacity =false ; };
이 딕셔너리는 다음 속성을 가집니다:
bytesSent
, 타입 unsigned long long, 기본값0
-
기저 연결(underlying connection)에서 송신된 바이트 수(재전송 포함). UDP 등 외부 프레이밍은 포함하지 않습니다.
packetsSent
, 타입 unsigned long long, 기본값0
-
기저 연결에서 송신된 패킷 수(손실로 판명된 패킷도 포함).
bytesLost
, 타입 unsigned long long, 기본값0
-
기저 연결에서 손실된 바이트 수(단조 증가하지 않을 수 있음, 손실로 선언된 패킷이 나중에 수신될 수 있음). UDP 등 외부 프레이밍은 포함하지 않습니다.
packetsLost
, 타입 unsigned long long, 기본값0
-
기저 연결에서 손실된 패킷 수(단조 증가하지 않을 수 있음, 손실로 선언된 패킷이 나중에 수신될 수 있음).
bytesReceived
, 타입 unsigned long long, 기본값0
-
기저 연결에서 수신된 총 바이트 수(스트림의 중복 데이터 포함). UDP 등 외부 프레이밍은 포함하지 않습니다.
packetsReceived
, 타입 unsigned long long, 기본값0
-
기저 연결에서 수신된 총 패킷 수(처리 불가 패킷도 포함).
smoothedRtt
, 타입 DOMHighResTimeStamprttVariation
, 타입 DOMHighResTimeStampminRtt
, 타입 DOMHighResTimeStamp-
전체 연결에서 관측된 최소 RTT입니다.
estimatedSendRate
, 타입 unsigned long long, nullable, 기본값null
-
사용자 에이전트가 대기 중인 데이터를 전송할 것으로 예상되는 속도(bps). 이 속도는 WebTransport 세션을 공유하는 모든 스트림과 데이터그램에 적용되며, 혼잡 제어 알고리즘(예:
congestionControl
)에 의해 계산됩니다. 프레이밍 오버헤드는 제외하며, 실제 애플리케이션 페이로드 전송 속도를 나타냅니다. 사용자 에이전트가 현재 추정값을 갖고 있지 않으면null
이어야 합니다. 이전 결과에서는 null이 아니었더라도 현재 null일 수 있습니다. atSendCapacity
, 타입 boolean, 기본값false
-
false이면
estimatedSendRate
값이 애플리케이션에 의해 제한됨을 의미합니다. 즉, 애플리케이션이 혼잡 제어기가 허용하는 것보다 훨씬 적은 데이터를 전송하고 있을 수 있습니다. 혼잡 제어기가 네트워크 용량을 잘못 추정할 수 있습니다.true이면 애플리케이션이 네트워크 용량만큼 데이터를 보내고 있고,
estimatedSendRate
값이 애플리케이션에 허용된 네트워크 용량을 반영합니다.atSendCapacity
가true
일 때,estimatedSendRate
값은 상한값(ceiling)을 나타냅니다. 애플리케이션이 지속적으로 데이터를 전송하면estimatedSendRate
는 네트워크 환경에 따라 적응합니다. 하지만estimatedSendRate
는null
일 수도 있습니다(atSendCapacity
가 true여도).
6.14.
WebTransportDatagramStats
딕셔너리
WebTransportDatagramStats
딕셔너리는 기저 연결을 통한
데이터그램 전송에 대한 통계를 포함합니다.
dictionary WebTransportDatagramStats {unsigned long long droppedIncoming = 0;unsigned long long expiredIncoming = 0;unsigned long long expiredOutgoing = 0;unsigned long long lostOutgoing = 0; };
이 딕셔너리는 다음 속성을 가집니다:
droppedIncoming
, 타입 unsigned long long, 기본값0
-
애플리케이션이
datagrams
의readable
에서 읽기 전에, 새 데이터그램이 수신 큐를 넘치게 하여 드롭된 수신 데이터그램의 개수입니다. expiredIncoming
, 타입 unsigned long long, 기본값0
-
수신된 데이터그램이
incomingMaxAge
보다 오래되어datagrams
의readable
에서 읽히기 전에 드롭된 개수입니다. expiredOutgoing
, 타입 unsigned long long, 기본값0
-
송신 대기 중인 데이터그램이
outgoingMaxAge
보다 오래되어 전송되기 전에 드롭된 개수입니다. lostOutgoing
, 타입 unsigned long long, 기본값0
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]]
와 다르다면, InvalidStateError 예외를InvalidStateError
로 throw합니다. -
this.
[[SendGroup]]
에 value를 설정합니다.
-
sendOrder
, 타입 long long-
getter 단계:
-
this의
[[SendOrder]]
를 반환합니다.
setter 단계, value가 주어진 경우:
-
this.
[[SendOrder]]
에 value를 설정합니다.
-
7.2. 메서드
getStats()
-
이
WebTransportSendStream
의 성능과 관련된 통계를 수집하여, 결과를 비동기로 보고합니다.getStats가 호출되면, 유저 에이전트는 다음 단계를 실행해야 합니다:
-
p를 새로운 promise로 둡니다.
-
다음 단계를 병렬로 실행합니다:
-
이
WebTransportSendStream
에 대한 통계를 수집합니다. -
통계가 준비될 때까지 대기합니다.
-
네트워크 작업을 큐에 넣습니다. transport로 다음 단계를 실행:
-
수집된 통계를 나타내는 stats를 new
WebTransportSendStreamStats
객체로 생성합니다. -
Resolve p를 stats로 해결합니다.
-
-
-
p를 반환합니다.
-
getWriter()
-
이 메서드는
getWriter
를WritableStream
에서 상속받은 것과 동일한 방식으로 구현되어야 하지만,WritableStreamDefaultWriter
를 생성하는 대신, WebTransportWriter를WebTransportWriter
로 this와 함께 생성해야 합니다.
7.3. 내부 슬롯
WebTransportSendStream
은 다음의 내부 슬롯을 가집니다.
내부 슬롯 | 설명 (비규범적) |
---|---|
[[InternalStream]]
| 출발지 단방향 또는 양방향 WebTransport 스트림입니다. |
[[PendingOperation]]
| 보류 중인 쓰기 또는 닫기 작업을 나타내는 promise, 또는 null. |
[[Transport]]
| 이 WebTransport 가
소유하는 WebTransportSendStream 입니다.
|
[[SendGroup]]
| 옵션의 WebTransportSendGroup ,
또는 null.
|
[[SendOrder]]
| 옵션의 전송 순서 번호, 기본값은 0. |
[[AtomicWriteRequests]]
| ordered set의 promise 집합으로, 기본 싱크에 의해 처리 대기 중인 원자적 쓰기 요청의 부분집합을 추적합니다. |
[[BytesWritten]]
| 스트림에 기록된 바이트 수. |
[[CommittedOffset]]
| 스트림 내 오프셋으로, 리셋되어도 피어에게 전달될 바이트 수를 기록합니다; [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에 chunk를 쓰려면 다음 단계를 실행합니다:
-
transport을 stream.
[[Transport]]
로 둡니다. -
chunk가
BufferSource
가 아니면, 거절된 promise를TypeError
와 함께 반환합니다. -
promise를 새로운 promise로 둡니다.
-
bytes를 chunk가 나타내는 바이트 시퀀스의 복사본으로 둡니다.
-
stream.
[[PendingOperation]]
를 promise로 설정합니다. -
inFlightWriteRequest를 stream.inFlightWriteRequest로 둡니다.
-
atomic을 stream.
[[AtomicWriteRequests]]
가 inFlightWriteRequest를 포함하면 true, 그렇지 않으면 false로 둡니다. -
다음 단계들을 병렬로 실행합니다:
-
atomic이 true이고, 현재 흐름 제어 윈도우가 bytes 전체를 보내기에 너무 작으면, 나머지 단계를 중단하고 네트워크 작업을 큐에 넣고 transport에서 다음 하위 단계 실행:
-
stream.
[[PendingOperation]]
를 null로 설정합니다. -
모든 원자적 쓰기 요청 중단을 stream에 수행합니다.
-
-
그 외의 경우, 전송 bytes를 stream.
[[InternalStream]]
에서 보내고 작업이 완료될 때까지 대기합니다. 이 전송은 이전에 큐에 넣은 스트림 또는 데이터그램의 전송과, 앞으로 큐에 넣을 스트림 또는 데이터그램의 전송과 interleave될 수 있습니다.유저 에이전트는 전송 성능 향상을 위해 버퍼를 둘 수 있습니다. 이러한 버퍼는 고정된 상한값을 가져야 하며,
WebTransportSendStream
사용자에게 backpressure 정보를 전달해야 합니다.이 전송은 같은
[[SendGroup]]
과 더 높은[[SendOrder]]
를 가진 스트림에 큐된 모든 바이트가 먼저 전송되어야만 차단됩니다. 해당 스트림들이 에러 상태가 아니고, 흐름 제어로 인해 차단되지 않아야 합니다.stream.
[[SendOrder]]
를 병렬로 접근합니다. 유저 에이전트는 전송 중 해당 값의 실시간 업데이트에 반응해야 하지만, 자세한 동작은 구현 정의입니다.참고: 재전송의 순서는 구현 정의이지만, 유저 에이전트는 더 높은
[[SendOrder]]
값을 가진 데이터의 재전송을 우선시해야 합니다.이 전송은 다른 이유로 차단되어서는 안 되며, 단지 흐름 제어나 에러에 의해서만 차단될 수 있습니다.
유저 에이전트는 차단되지 않은 모든 스트림에 대해 대역폭을 공정하게 분배해야 합니다.
참고: 여기서의 공정성 정의는 구현 정의입니다.
-
이전 단계가 네트워크 오류로 실패하면, 나머지 단계를 중단합니다.
참고: 여기서 promise를 거절하지 않는 이유는, 네트워크 오류는 별도의 단계에서 처리되며 그 단계에서 stream.
[[PendingOperation]]
를 거절하기 때문입니다. -
그 외의 경우, 네트워크 작업을 큐에 넣고 transport에서 다음 단계 실행:
-
stream.
[[PendingOperation]]
를 null로 설정합니다. -
bytes의 길이를 stream.
[[BytesWritten]]
에 더합니다. -
stream.
[[AtomicWriteRequests]]
가 inFlightWriteRequest를 포함하는 경우, inFlightWriteRequest를 제거합니다. -
promise를 undefined로 해결합니다.
-
-
-
promise를 반환합니다.
참고: 이 알고리즘(또는
write(chunk)
)에서
반환된 promise가
반드시 서버가 ack했다는 뜻은 아닙니다.
단지 버퍼에 추가되었음을 의미할 수 있습니다. 서버에 정상적으로 도달했는지 확인하려면, 서버가 응용 계층의 확인 메시지를 보내야 합니다.
[QUIC]
WebTransportSendStream
stream을 닫으려면 다음 단계를 실행합니다:
-
transport를 stream.
[[Transport]]
로 둡니다. -
promise를 새로운 promise로 둡니다.
-
stream을 transport.
[[SendStreams]]
에서 제거합니다. -
stream.
[[PendingOperation]]
를 promise로 설정합니다. -
다음 단계들을 병렬로 실행합니다:
-
FIN 전송을 stream.
[[InternalStream]]
에서 수행하고, 작업이 완료될 때까지 대기합니다. -
stream.
[[InternalStream]]
가 "all data committed" 상태가 될 때까지 대기합니다. [QUIC] -
네트워크 작업을 큐에 넣고 transport에서 다음 단계 실행:
-
stream.
[[PendingOperation]]
를 null로 설정합니다. -
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]]
로 둡니다.참고: code의 유효값은 0에서 4294967295까지입니다. 기저 연결이 HTTP/3를 사용하면, code는 [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
로 발생시키고, 이 단계들을 중단합니다. -
비움을 stream.
[[AtomicWriteRequests]]
에 수행합니다. -
각 promise에 대해 requestsToAbort에서 promise를
AbortError
로 거절합니다.
7.5. 서버로부터 오는 STOP_SENDING 시그널
WebTransportSendStream
stream과 연관되어 있을 때 서버로부터
STOP_SENDING 시그널을 받으면, 다음 단계를 실행합니다:
-
transport를 stream.
[[Transport]]
로 둡니다. -
code를 STOP_SENDING 프레임에 부착된 응용 프로토콜 오류 코드로 둡니다. [QUIC]
참고: code의 유효값은 0에서 4294967295까지입니다. 기저 연결이 HTTP/3를 사용하면, code는 [WEB-TRANSPORT-HTTP3]에 따라 [0x52e4a40fa8db, 0x52e5ac983162]로 인코딩됩니다.
-
네트워크 작업을 큐에 넣고 transport에서 다음 단계 실행:
-
transport.
[[State]]
가"closed"
또는"failed"
이면, 이 단계들을 중단합니다. -
stream을 transport.
[[SendStreams]]
에서 제거합니다. -
error를 새로 생성된
WebTransportError
로 둡니다.source
값은"stream"
이고,streamErrorCode
값은 code입니다. -
stream.
[[PendingOperation]]
이 null이 아니면, stream.[[PendingOperation]]
를 error로 거절합니다. -
에러를 stream에 error로 발생시킵니다.
-
7.6. WebTransportSendStreamStats
사전
WebTransportSendStreamStats
사전은
하나의 WebTransportSendStream
에
특화된 통계 정보를 포함합니다.
dictionary WebTransportSendStreamStats {unsigned long long bytesWritten = 0;unsigned long long bytesSent = 0;unsigned long long bytesAcknowledged = 0; };
해당 사전은 다음 속성을 가집니다:
bytesWritten
, 타입 unsigned long long, 기본값0
-
애플리케이션이 해당
WebTransportSendStream
에 성공적으로 기록한 총 바이트 수입니다. 이 값은 오직 증가할 수 있습니다. bytesSent
, 타입 unsigned long long, 기본값0
-
해당
WebTransportSendStream
에 기록된 애플리케이션 바이트가 적어도 한 번 전송된 진행 상황을 나타냅니다. 이 값은 오직 증가할 수 있고,bytesWritten
값 이하입니다.참고: 이는 단일 스트림에서 전송된 앱 데이터의 진행 상황만을 나타내며, 네트워크 오버헤드는 포함하지 않습니다.
bytesAcknowledged
, 타입 unsigned long long, 기본값0
-
해당
WebTransportSendStream
에 기록된 애플리케이션 바이트 중 서버가 QUIC의 ACK 메커니즘을 통해 수신을 인정한 바이트 수를 나타냅니다. 확인되지 않은 첫 바이트를 제외하고, 그 이전까지의 연속된 바이트만 집계됩니다. 이 값도 오직 증가할 수 있고,bytesSent
값 이하입니다.참고: HTTP/2 환경에서는 이 값이
bytesSent
와 일치합니다.
8. 인터페이스 WebTransportSendGroup
WebTransportSendGroup
은 여러 개의 개별
(일반적으로 엄격하게
순서화된)
WebTransportSendStream
에
걸쳐 분산된 데이터 전송을 추적하는 선택적 조직 객체입니다.
WebTransportSendStream
은
생성 시 또는 sendGroup
속성 할당을 통해
언제든지 최대 하나의 WebTransportSendGroup
에
그룹화될 수 있습니다. 기본적으로는
그룹화되지 않음 상태입니다.
유저 에이전트는 WebTransportSendGroup
들에
대해 WebTransportSendStream
전송을 위한 대역폭 할당 시 동등하게 간주합니다.
각 WebTransportSendGroup
은
sendOrder
평가를 위한 독립적인 번호 공간도 제공합니다.
[Exposed =(Window ,Worker ),SecureContext ]interface {
WebTransportSendGroup Promise <WebTransportSendStreamStats >getStats (); };
WebTransportSendGroup
은 항상
create 절차에 의해 생성됩니다.
8.1. 메서드
getStats()
-
이 sendGroup에 그룹화된 모든
WebTransportSendStream
의 통계를 집계하여 비동기로 결과를 보고합니다.getStats가 호출되면, 유저 에이전트는 다음 단계를 실행해야 합니다:
-
p를 새로운 promise로 둡니다.
-
streams를
WebTransportSendStream
중[[SendGroup]]
이 this인 모든 스트림으로 둡니다. -
다음 단계들을 병렬로 실행합니다:
-
streams의 모든 스트림에서 통계 정보를 수집합니다.
-
네트워크 작업을 큐에 넣고 transport에서 다음 단계 실행:
-
수집된 통계의 집계 값을 나타내는 stats를 new
WebTransportSendStreamStats
객체로 생성합니다. -
promise를 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
은 읽기 바이트 스트림이며,
따라서 소비자가 BYOB 리더와 기본 리더 모두 사용할 수
있습니다.
[Exposed =(Window ,Worker ),SecureContext ,Transferable ]interface :
WebTransportReceiveStream ReadableStream {Promise <WebTransportReceiveStreamStats >getStats (); };
WebTransportReceiveStream
은 항상
create 절차에 의해 생성됩니다.
WebTransportReceiveStream
의
전송 단계 및
전송-수신 단계는
ReadableStream의 단계와 동일합니다.
9.1. 메서드
getStats()
-
이
WebTransportReceiveStream
의 성능에 특화된 통계를 수집하여, 결과를 비동기로 보고합니다.getStats가 호출되면, 유저 에이전트는 다음 단계를 실행해야 합니다:
-
p를 새로운 promise로 둡니다.
-
다음 단계들을 병렬로 실행합니다:
-
이
WebTransportReceiveStream
에 대한 통계를 수집합니다. -
네트워크 작업을 큐에 넣고 transport에서 다음 단계 실행:
-
수집된 통계를 나타내는 stats를 new
WebTransportReceiveStreamStats
객체로 생성합니다. -
promise를 stats로 해결합니다.
-
-
-
p를 반환합니다.
-
9.2. 내부 슬롯
WebTransportReceiveStream
은 다음 내부 슬롯을 가집니다.
내부 슬롯 | 설명 (비규범적) |
---|---|
[[InternalStream]]
| 수신 단방향 또는 양방향 WebTransport 스트림입니다. |
[[Transport]]
| 이 WebTransport
객체가 해당 WebTransportReceiveStream 를
소유합니다.
|
9.3. 절차
생성 절차로,
WebTransportReceiveStream
을
수신 단방향 또는 양방향 WebTransport
스트림
internalStream 및 WebTransport
transport로 생성하려면 다음 단계를 수행합니다:
-
stream을 new
WebTransportReceiveStream
으로 생성합니다. 다음과 같이 초기화합니다:[[InternalStream]]
-
internalStream
[[Transport]]
-
transport
-
pullAlgorithm을 stream으로부터 바이트를 풀하는 동작으로 둡니다.
-
cancelAlgorithm을 reason과 함께 stream을 취소하는 동작으로 둡니다.
-
바이트 읽기 지원으로 설정을 stream에 pullAlgorithm을 pullAlgorithm으로, cancelAlgorithm을 cancelAlgorithm으로 설정합니다.
-
Append stream을 transport.
[[ReceiveStreams]]
에 추가합니다. -
stream을 반환합니다.
바이트 풀 절차로,
WebTransportReceiveStream
stream에서 바이트를 풀하려면 다음 단계를 실행합니다.
-
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를 구현 정의 크기로 둡니다.
-
buffer를 new
ArrayBuffer
로 maxBytes 크기로 둡니다.ArrayBuffer
할당이 실패하면, 거절된 promise를RangeError
와 함께 반환합니다.
-
-
다음 단계들을 병렬로 실행합니다:
-
쓰기를 읽은 바이트를 internalStream에서 buffer의 offset 위치에 최대 maxBytes 바이트까지 기록합니다. 최소 한 바이트가 읽히거나 FIN이 수신될 때까지 대기합니다. read를 읽은 바이트 수로, hasReceivedFIN을 FIN이 동반되었는지 여부로 둡니다.
유저 에이전트는 전송 성능 향상을 위해 버퍼를 둘 수 있습니다. 이러한 버퍼는 고정된 상한값을 가져야 하며, 서버로 backpressure 정보를 전달해야 합니다.
참고: 이 동작은 buffer 전체를 채우기 전에 반환될 수 있습니다.
-
이전 단계가 실패하면, 나머지 단계를 중단합니다.
참고: 여기서 promise를 거절하지 않는 이유는, 네트워크 오류는 별도의 단계에서 처리되며 그 단계에서 에러가 stream에 발생되어 해당 풀을 대기 중인 읽기 요청이 거절되기 때문입니다.
-
네트워크 작업을 큐에 넣고 transport에서 다음 단계 실행:
참고: 위의 버퍼가 해당 이벤트 루프에 존재하면, 아래 단계가 즉시 실행될 수 있습니다.
-
read > 0이면:
-
view를 buffer, offset, read로 새로운
Uint8Array
로 둡니다. -
Enqueue view를 stream에 넣습니다.
-
-
hasReceivedFIN이 true이면:
-
Remove stream을 transport.
[[ReceiveStreams]]
에서 제거합니다. -
Close stream을 닫습니다.
-
-
promise를 undefined로 해결합니다.
-
-
-
promise를 반환합니다.
취소 절차로,
WebTransportReceiveStream
stream을 reason과 함께 취소하려면 다음 단계를 실행합니다.
-
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로 설정합니다.
참고: code의 유효값은 0에서 4294967295까지입니다. 기저 연결이 HTTP/3를 사용하면, code는 [WEB-TRANSPORT-HTTP3]에 따라 [0x52e4a40fa8db, 0x52e5ac983162]로 인코딩됩니다.
-
Remove stream을 transport.
[[SendStreams]]
에서 제거합니다. -
다음 단계들을 병렬로 실행합니다:
-
STOP_SENDING 전송을 internalStream과 code로 실행합니다.
-
네트워크 작업을 큐에 넣고 transport에서 다음 단계 실행:
참고: 위의 버퍼가 해당 이벤트 루프에 존재하면, 아래 단계가 즉시 실행될 수 있습니다.
-
Remove stream을 transport.
[[ReceiveStreams]]
에서 제거합니다. -
promise를 undefined로 해결합니다.
-
-
-
promise를 반환합니다.
9.4. 서버로부터 오는 Reset 신호
WebTransportReceiveStream
stream과 연관되어 있을 때 서버로부터
RESET_STREAM 신호를 받으면, 다음 단계를 실행합니다:
-
transport를 stream.
[[Transport]]
로 둡니다. -
code를 RESET_STREAM_AT 또는 WT_RESET_STREAM 프레임에 부착된 응용 프로토콜 오류 코드로 둡니다. [RELIABLE-RESET] [WEB-TRANSPORT-HTTP2]
참고: code의 유효값은 0에서 4294967295까지입니다. 기저 연결이 HTTP/3를 사용하면, code는 [WEB-TRANSPORT-HTTP3]에 따라 [0x52e4a40fa8db, 0x52e5ac983162]로 인코딩됩니다.
-
네트워크 작업을 큐에 넣고 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 = 0;unsigned long long bytesRead = 0; };
해당 사전은 다음 속성을 가집니다:
bytesReceived
, 타입 unsigned long long, 기본값0
-
서버 애플리케이션이 해당
WebTransportReceiveStream
에 전달하고자 한 바이트 중 지금까지 수신된 진행 상황을 나타냅니다. 확인되지 않은 첫 바이트를 제외하고, 그 이전까지의 연속된 바이트만 집계됩니다. 이 값은 오직 증가할 수 있습니다.참고: 이는 단일 스트림에서 수신된 앱 데이터의 진행 상황만을 나타내며, 네트워크 오버헤드는 포함하지 않습니다.
bytesRead
, 타입 unsigned long long, 기본값0
-
애플리케이션이 해당
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. 절차
WebTransportBidirectionalStream
을 양방향
WebTransport 스트림 internalStream, WebTransport
객체 transport, sendOrder와 함께 생성하려면 다음 단계를 실행합니다.
-
readable을 WebTransportReceiveStream 생성의 결과로 둡니다. internalStream과 transport를 사용합니다.
-
writable을 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]]
)로 갱신합니다. 이렇게 하면 그 바이트들이 중단되어 스트림이 리셋되더라도 피어에게 신뢰성 있게 전달됨이 보장됩니다. [RELIABLE-RESET]의 메커니즘을 사용합니다.참고: 이는 연결 실패 상황까지 전달을 보장하지는 않으며, 스트림이 리셋될 때만 보장됩니다.
commit
이 stream에 대해 호출되면, 유저 에이전트는 다음 단계를 실행해야 합니다:-
transport를 stream.
[[Transport]]
로 둡니다. -
stream.
[[CommittedOffset]]
를 stream.[[BytesWritten]]
값으로 설정합니다.
-
11.2. 절차
생성 절차로,
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, readonly-
getter 단계는 this의
[[Source]]
를 반환하는 것입니다. streamErrorCode
, 타입 unsigned long, readonly, 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 효과 |
---|---|
세션 drained | await wt.draining
|
기저 연결이 HTTP/3를 사용하는 경우, [WEB-TRANSPORT-HTTP3]의 다음 프로토콜 동작이 적용됩니다.
WebTransportError
오류에서 application streamErrorCode
값은 httpErrorCode로 변환되며, 반대도 마찬가지입니다. 자세한 내용은 [WEB-TRANSPORT-HTTP3]
Section 4.3을
참고하세요.
API 메서드 | QUIC 프로토콜 동작 |
---|---|
writable .abort (error)
| RESET_STREAM_AT를 httpErrorCode와
해당 [[CommittedOffset]]
오프셋(스트림 헤더 포함)으로 전송; 자세한 내용은 [RELIABLE-RESET] 참고
|
writable .close ()
| STREAM FIN 비트 설정하여 전송 |
writable .getWriter().write(chunk) ()
| STREAM 전송 |
writable .getWriter().close ()
| STREAM FIN 비트 설정하여 전송 |
writable .getWriter().abort (error)
| RESET_STREAM_AT를 httpErrorCode와
해당 [[CommittedOffset]]
오프셋(스트림 헤더 포함)으로 전송; 자세한 내용은 [RELIABLE-RESET] 참고
|
readable .cancel (error)
| STOP_SENDING을 httpErrorCode와 함께 전송 |
readable .getReader().cancel (error)
| STOP_SENDING을 httpErrorCode와 함께 전송 |
wt.close (closeInfo)
| 세션
종료 (closeInfo 포함) |
QUIC 프로토콜 동작 | API 효과 |
---|---|
httpErrorCode와 함께 STOP_SENDING 수신 | 에러 발생 writable
(streamErrorCode
포함)
|
STREAM 수신 | (await
readable .getReader().read ()).value
|
STREAM FIN 비트 설정 수신 | (await
readable .getReader().read ()).done
|
httpErrorCode와 함께 RESET_STREAM 수신 | 에러 발생 readable
(streamErrorCode
포함)
|
세션이 clean하게 종료됨 (closeInfo 포함) | (await wt.closed ).closeInfo,
그리고
에러 발생 열린 스트림들
|
네트워크 오류 | (await wt.closed )
rejected, 그리고
에러 발생 열린 스트림들
|
참고: [QUIC]의 Section 3.2에서 논의된 대로, RESET_STREAM 또는 RESET_STREAM_AT 프레임([RELIABLE-RESET])의 수신이 애플리케이션에 항상 즉시 표시되는 것은 아닙니다. 리셋 신호는 즉시 전달되어 스트림 데이터 전달을 중단시키고, 소비되지 않은 데이터는 폐기될 수 있습니다. 그러나 즉각적 신호가 필수는 아닙니다. 특히 Reliable Size 필드가 있는 RESET_STREAM_AT 프레임의 데이터를 전달하기 위해 신호가 지연될 수 있습니다. 스트림 데이터가 모두 수신되었지만 애플리케이션이 아직 읽지 않았다면 신호가 생략될 수 있습니다. WebTransport는 스트림 헤더의 신뢰성 있는 전달을 보장하기 위해 항상 RESET_STREAM_AT 프레임을 사용합니다; 자세한 내용은 Section 4.1 및 Section 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_RESET_STREAM을 error와 함께 전송 |
writable .close ()
| WT_STREAM FIN 비트 설정하여 전송 |
writable .getWriter().write ()
| WT_STREAM 전송 |
writable .getWriter().close ()
| WT_STREAM FIN 비트 설정하여 전송 |
writable .getWriter().abort (error)
| WT_RESET_STREAM을 error와 함께 전송 |
readable .cancel (error)
| WT_STOP_SENDING을 error와 함께 전송 |
readable .getReader().cancel (error)
| WT_STOP_SENDING을 error와 함께 전송 |
wt.close (closeInfo)
| 세션
종료 (closeInfo 포함) |
HTTP/2 프로토콜 동작 | API 효과 |
---|---|
error와 함께 WT_STOP_SENDING 수신 | 에러 발생 writable
(streamErrorCode
포함)
|
WT_STREAM 수신 | (await
readable .getReader().read ()).value
|
WT_STREAM FIN 비트 설정 수신 | (await
readable .getReader().read ()).done
|
error와 함께 WT_RESET_STREAM 수신 | 에러 발생 readable
(streamErrorCode
포함)
|
세션이 clean하게 종료됨 (closeInfo 포함) | (await wt.closed ).closeInfo,
그리고
에러 발생 열린 스트림들
|
네트워크 오류 | (await wt.closed )
rejected, 그리고
에러 발생 열린 스트림들
|
세션 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 프로토콜을 사용 중임을 인지하고, 사용에 동의하도록 보장합니다. [WEB-TRANSPORT-HTTP3]는 ALPN [RFC7301], HTTP/3 세팅,
:protocol
의사 헤더 조합을 사용합니다. [WEB-TRANSPORT-HTTP2]도 ALPN, HTTP/2 세팅,:protocol
의사 헤더를 사용합니다. -
서버가 자원을 시작한 트랜스포트 세션의 origin에 따라 연결을 필터링하도록 허용합니다. 세션 설정 요청의
Origin
헤더 필드가 이 정보를 전달합니다.
프로토콜 보안 관련 고려사항은 Security Considerations 섹션([WEB-TRANSPORT-HTTP3], [WEB-TRANSPORT-HTTP2])에 기술되어 있습니다.
네트워킹 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
리더를 얻을 수 있습니다.
이를 통해 복사를 피하고 버퍼 할당을 더 정밀하게 제어할 수 있습니다. 이 예시는 64kB 메모리 버퍼로 데이터그램을 읽습니다.
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
은
바이트 스트림이므로,
BYOB
리더를 얻을 수 있습니다.
이를 통해 복사를 피하고 버퍼 할당을 더 정밀하게 제어할 수 있습니다. 이 예시는 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에서 처음 기술되었습니다.
이 명세서에 맞게 적용되었습니다.