가까운 오리진 트라이얼에서 RTCQuicTransport 제공 (Chrome 73)

대상

RTCQuicTransport는 QUIC 프로토콜을 사용하여 원격 피어와 임의의 데이터를 교환할 수 있는 새로운 웹 플랫폼 API입니다. P2P 사용 사례를 위한 것이므로 독립형 RTCIceTransport API와 함께 ICE를 통해 P2P 연결을 설정하는 데 사용됩니다. 데이터는 안정적으로 순서대로 전송됩니다 (주문되지 않은 전송 및 신뢰할 수 없는 전송에 관한 자세한 내용은 아래 섹션 참고). 일반적인 양방향 데이터 전송이므로 게임, 파일 전송, 미디어 전송, 메시지 등에 사용할 수 있습니다.

왜냐하면

강력한 하위 수준 데이터 전송 API를 사용하면 애플리케이션 (예: 실시간 통신)이 웹에서 새로운 작업을 수행할 수 있습니다. API를 기반으로 빌드하여 자체 솔루션을 만들면 P2P 연결로 할 수 있는 작업의 한계를 뛰어넘을 수 있습니다(예: 맞춤 비트 전송률 할당 노브 잠금 해제). 향후 인코딩된 미디어가 추가로 지원되면 하위 수준의 컨트롤을 사용하여 자체 동영상 통신 애플리케이션을 빌드할 수도 있습니다. WebRTC의 NV는 하위 수준의 API로 전환하기 위한 노력으로 조기에 이 API를 실험하는 것이 매우 중요합니다.

QUIC을 사용해야 하는 이유

QUIC 프로토콜은 실시간 통신에 적합합니다. UDP를 기반으로 빌드되고 암호화 및 정체 제어가 내장되어 있으며 대기 행렬 막힘 없이 다중화됩니다. RTCQuicTransportRTCDataChannel API와 매우 유사한 기능을 제공하지만 전송 프로토콜로 SCTP가 아닌 QUIC를 사용합니다. RTCQuicTransport는 독립형 API이므로 실시간 미디어 스택이 포함된 RTCPeerConnection API의 오버헤드가 없습니다.

방법

일반 API 개요

API에는 RTCIceTransport, RTCQuicTransport, RTCQuicStream의 3가지 기본 추상화가 있습니다.

API의 아키텍처를 보여주는 RTCQuicTransport 다이어그램

RTCIceTransport

ICE는 인터넷을 통해 P2P 연결을 설정하는 프로토콜이며 오늘날 WebRTC에서 사용됩니다. 이 객체는 ICE 연결을 설정하는 독립형 API를 제공합니다. 이 명령어는 QUIC 연결을 위한 패킷 전송으로 사용되며, RTCQuicTransport는 이를 생성자로 가져옵니다.

RTCQuicTransport

QUIC 연결을 나타냅니다. QUIC 연결을 설정하고 QUIC 스트림을 만드는 데 사용됩니다. 또한 QUIC 연결 수준의 관련 통계를 노출합니다.

RTCQuicStream

원격 측에서 데이터를 읽고 쓰는 데 사용됩니다. 스트림은 데이터를 안정적이고 순서대로 전송합니다. 동일한 RTCQuicTransport에서 여러 스트림을 만들 수 있으며 데이터가 스트림에 기록되면 원격 전송에서 'onquicstream' 이벤트가 실행됩니다. 스트림은 동일한 QUIC 연결에서 서로 다른 데이터를 구별하는 방법을 제공합니다. 일반적인 예로는 별도의 스트림 간에 별도의 파일을 전송하거나 여러 스트림에 작은 데이터 청크를 전송하거나 여러 유형의 미디어를 개별 스트림에 전송할 수 있습니다. RTCQuicStream는 가볍고, QUIC 연결을 통해 다중화되며, 다른 RTCQuicStream에 대한 대기 행렬 막힘을 일으키지 않습니다.

연결 설정

다음은 P2P QUIC 연결을 설정하는 예입니다. RTCPeerConnection와 마찬가지로 RTCQuicTransport API에서도 보안 매개변수를 포함한 연결 매개변수를 협상하기 위해 보안 신호 채널을 사용해야 합니다. RTCIceTransport는 ICE 매개변수 (ufrag 및 비밀번호)와 RTCIceCandidate를 협상합니다.

API의 아키텍처를 보여주는 RTCQuicTransport 다이어그램

고객의 관점:

const iceTransport = new RTCIceTransport();
const quicTransport = new RTCQuicTransport(iceTransport);
// Signal parameters, key and candidates.
signalingChannel.send({
  iceParams: iceTransport.getLocalParameters(),
  quicKey: quicTransport.getKey(),
});
iceTransport.onicecandidate = e => {
  if (e.candidate) {
    signalingChannel.send({candidate: e.candidate});
  }
};

// When remote parameters are signaled, start connection.
signalingChannel.onMessage = async ({iceParams, candidate}) => {
  if (iceParams) {
    iceTransport.start(iceParams);
    quicTransport.connect();
  } else if (candidate) {
    iceTransport.addRemoteCandidate(candidate);
  }
};

서버 관점:

const iceTransport = new RTCIceTransport();
const quicTransport = new RTCQuicTransport(iceTransport);
// Signal parameters, key and candidates.
signalingChannel.send({
  iceParams: iceTransport.getLocalParameters(),
});
iceTransport.onicecandidate = e => {
  if (e.candidate) {
    signalingChannel.send({candidate: e.candidate});
  }
};

// When remote parameters are signaled, start connection.
signalingChannel.onMessage = async ({iceParams, quicKey, candidate}) => {
  if (iceParams && quicKey) {
    iceTransport.start(iceParams);
    quicTransport.listen(quicKey);
  } else if (candidate) {
    iceTransport.addRemoteCandidate(candidate);
  }
};

Data Transfer

데이터 전송은 RTCQuicStream API를 사용하여 읽고 쓸 수 있습니다.

RTCQuicStreamReadResult readInto(Uint8Array data);
void write(RTCQuicStreamWriteParameters data);
Promise<void> waitForWriteBufferedAmountBelow(unsigned long amount);
Promise<void> waitForReadable(unsigned long amount);

버퍼링

waitFor* 메서드에서 반환하는 프로미스를 통해 JavaScript를 사용 중일 때 데이터 버퍼링이 허용됩니다. 수신 측에서 읽기 버퍼가 가득 차면 백 프레셔가 전송 측에 적용됩니다. 백 프레셔가 적용되어 있을 때 채울 수 있는 쓰기 버퍼가 전송 측에 있습니다. 따라서 쓰기 측에는 버퍼에서 쓰기 공간이 발생할 때까지 대기할 수 있도록 waitForWriteBufferedAmountBelow 메서드도 있습니다. 데이터 쓰기/읽기에 관한 자세한 내용은 추가 개발자 문서를 참고하세요.

주문되지 않은/신뢰할 수 없는 배송

RTCQuicStream는 데이터를 안정적이고 순서대로 전송하는 것만 지원하지만 다른 수단을 통해서는 신뢰할 수 없거나 순서가 지정되지 않은 전송도 가능합니다. 정렬되지 않은 전송의 경우 데이터가 스트림 간에 정렬되지 않으므로 별도의 스트림에서 작은 데이터 청크를 전송할 수 있습니다. 불안정한 전송을 위해, 완료가 true로 설정된 작은 데이터 청크를 전송한 후 시간 초과 후 스트림에서 reset()를 호출할 수 있습니다. 제한 시간은 데이터를 삭제하기 전에 원하는 재전송 횟수에 따라 달라집니다.

시기

오리진 트라이얼은 Chrome 73 버전에서 시작되며 M75 버전까지 사용할 수 있습니다. 이후에는 오리진 트라이얼이 종료됩니다. Google은 의견과 관심에 따라 적절하게 변경한 후 API를 출시하거나, 이 API의 새로운 오리진 트라이얼을 계속 사용하거나, API를 중단할 예정입니다.

위치

iOS를 제외한 모든 플랫폼의 Chrome 브라우저

안 되는 사람이랄까?

의견

오리진 트라이얼의 주요 목표 중 하나는 개발자의 의견을 받는 것입니다. Google의 관심 분야:

  • 이 API를 통해 무엇을 할 수 있나요?
  • 이 API가 다른 데이터 전송 API(WebSocket 또는 WebRTC의 RTCDataChannel)보다 어떻게 개선되나요? 어떻게 개선할 수 있을까요?
  • 성능
  • API 에르고노믹스

오리진 트라이얼 등록

  1. 출처의 토큰을 요청합니다.
  2. 페이지에 토큰을 추가합니다. 출처의 모든 페이지에 이 토큰을 제공하는 방법에는 두 가지가 있습니다.
    • 페이지 헤드에 origin-trial <meta> 태그를 추가합니다. 예를 들어 다음과 같을 수 있습니다. <meta http-equiv="origin-trial" content="TOKEN_GOES_HERE">
    • 서버를 구성할 수 있는 경우 Origin-Trial HTTP 헤더를 사용하여 페이지에 토큰을 제공할 수도 있습니다. 결과 응답 헤더는 Origin-Trial: TOKEN_GOES_HERE와 같이 표시됩니다.

웹 사양

오리진 트라이얼에서 다음과 같은 초안 사양이 API보다 먼저 제공됩니다.

  • WhatWG 스트림과 더 밀접하게 정렬된 단방향 스트림
  • 재전송 사용 중지
  • (제공 예정) 데이터그램

Google은 전체 사양 및 그 이상 (WhatWG 스트림 지원 포함)을 구현하는 데 관심이 있지만 먼저 여러분의 의견을 듣고자 합니다.

보안

QUIC 핸드셰이크의 보안은 암호화된 P2P QUIC 연결을 설정하기 위한 사전 공유 키를 사용하여 시행됩니다. 이 키는 비밀유지와 무결성이 보장되는 대역 외 보안 채널을 통해 신호를 보내야 합니다. 키는 자바스크립트에 노출됩니다.

활성 공격

인증서 지문을 알리기 위해 무결성만 필요한 DTLS-SRTP와 달리 사전 공유 키를 나타내려면 무결성과 기밀성이 필요합니다. PSK가 손상되면 (예: 신호 채널의 서버에 의해) 활성 공격자가 잠재적으로 QUIC 핸드셰이크에 대해 중간자 공격을 마운트할 수 있습니다.

현재 상태

단계 상태
1. 설명 만들기 완료
**2a. RTCQuicTransport 사양 ** **진행 중**
**2b. RTCIceTransport 사양 ** **진행 중**
**3. 피드백 수렴 및 디자인 반복** **진행 중**
4. 오리진 트라이얼 Chrome 73에서 시작됩니다.
5. 출시 Not started

유용한 링크