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

내용

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

왜냐하면

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

QUIC를 사용해야 하는 이유

QUIC 프로토콜은 실시간 통신에 적합합니다. UDP를 기반으로 하며 암호화, 혼잡 제어를 내장하고 선두 블로킹 없이 멀티플렉스됩니다. RTCQuicTransportRTCDataChannel API와 매우 유사한 기능을 제공하지만 전송 프로토콜로 SCTP 대신 QUIC을 사용합니다. RTCQuicTransport는 독립형 API이므로 실시간 미디어 스택이 포함된 RTCPeerConnection API의 오버헤드가 없습니다.

방법

일반 API 개요

이 API에는 세 가지 주요 추상화인 RTCIceTransport, RTCQuicTransport, RTCQuicStream가 있습니다.

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

RTCIceTransport

ICE는 인터넷을 통해 P2P 연결을 설정하는 프로토콜로, 현재 WebRTC에서 사용됩니다. 이 객체는 ICE 연결을 설정하는 독립형 API를 제공합니다. QUIC 연결의 패킷 전송으로 사용되며 RTCQuicTransport는 생성자에서 이를 사용합니다.

RTCQuicTransport

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

RTCQuicStream

원격 측면에서 데이터를 읽고 쓰는 데 사용됩니다. 스트림은 데이터를 안정적이고 순서대로 전송합니다. 동일한 RTCQuicTransport에서 여러 스트림을 만들 수 있으며 데이터가 스트림에 쓰여지면 원격 전송에서 'onquicstream' 이벤트가 발생합니다. 스트림은 동일한 QUIC 연결에서 서로 다른 데이터를 구분하는 방법을 제공합니다. 일반적인 예로는 별도의 스트림에 별도의 파일을 전송하거나, 여러 스트림에 작은 데이터 청크를 전송하거나, 여러 스트림에 서로 다른 유형의 미디어를 전송하는 경우가 있습니다. RTCQuicStream는 가볍고 QUIC 연결을 통해 멀티플렉스되며 다른 RTCQuicStream의 헤드 오브 라인 차단을 일으키지 않습니다.

연결 설정

다음은 피어 투 피어 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);
  }
};

데이터 전송

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는 데이터를 안정적이고 순서대로 전송하는 것만 지원하지만, 안정적이지 않거나 순서가 지정되지 않은 전송은 다른 수단을 통해 실행할 수 있습니다. 순서 없는 전송의 경우 데이터가 스트림 간에 정렬되지 않으므로 별도의 스트림에서 소량의 데이터를 전송할 수 있습니다. 안정적이지 않은 전송의 경우 finish를 true로 설정하여 작은 데이터 청크를 전송한 다음 시간 초과 후 스트림에서 reset()를 호출할 수 있습니다. 제한 시간은 데이터를 삭제하기 전에 원하는 재전송 횟수에 따라 달라야 합니다.

일시

오리진 트라이얼은 Chrome 73 버전에서 시작되며 M75 버전까지 사용할 수 있습니다. 이 후에는 원본 무료 체험이 종료됩니다. 의견과 관심에 따라 적절하게 변경하고 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 연결을 설정하는 방식으로 적용됩니다. 이 키는 기밀 유지 및 무결성 보장이 있는 보안 비표준 채널을 통해 신호를 전송해야 합니다. 키가 JavaScript에 노출됩니다.

활성 공격

인증서 지문 신호에만 무결성이 필요한 DTLS-SRTP와 달리 사전 공유 키 신호에는 무결성과 기밀성이 필요합니다. PSK가 손상되면 (예: 신호 채널의 서버에 의해) 활동 중인 공격자가 QUIC 핸드셰이크에 중간자 공격을 시도할 수 있습니다.

현재 상태

단계 상태
1. 설명 동영상 만들기 완전함
**2a. RTCQuicTransport 사양 ** **진행 중**
**2b. RTCIceTransport 사양 ** **진행 중**
**3. 의견 수집 및 디자인 반복** **진행 중**
4. 오리진 트라이얼 Chrome 73부터 시작됩니다.
5. 출시 시작되지 않음

유용한 링크