WebRTC 데이터 채널을 사용하여 브라우저 간 데이터 전송

통신, 게임 또는 파일 전송을 위해 두 브라우저 간에 데이터를 보내는 것은 다소 복잡한 과정일 수 있습니다. 데이터를 릴레이하기 위해 서버를 설정하고 비용을 지불해야 하며 이를 여러 데이터 센터로 확장해야 할 수 있습니다. 이 시나리오에서는 지연 시간이 길어질 수 있으며 데이터를 비공개로 유지하기가 어렵습니다.

WebRTC의 RTCDataChannel API를 사용하여 피어 간에 데이터를 직접 전송하면 이러한 문제를 완화할 수 있습니다. 이 도움말에서는 데이터 채널을 설정하고 사용하는 방법에 대한 기본사항과 오늘날 웹에서의 일반적인 사용 사례를 설명합니다.

다른 데이터 채널을 사용해야 하는 이유

WebSocket, AJAX서버 전송 이벤트가 있습니다. 다른 커뮤니케이션 채널이 필요한 이유는 무엇인가요? WebSocket은 양방향이지만, 이러한 모든 기술은 서버와의 통신을 위해 설계되었습니다.

RTCDataChannel는 다른 접근 방식을 사용합니다.

  • P2P 연결을 사용 설정하는 RTCPeerConnection API와 호환됩니다. 따라서 지연 시간이 단축될 수 있습니다. 중간 서버가 없고 '홉'이 줄어듭니다.
  • RTCDataChannel스트림 제어 전송 프로토콜 (SCTP)을 사용하여 구성 가능한 전송 시맨틱스를 순서에 맞지 않는 전송과 재전송 구성을 허용합니다.

이제 RTCDataChannel이(가) 데스크톱 및 Android의 Chrome, Opera, Firefox에서 SCTP를 통해 지원됩니다.

주의사항: 신호, STUN, TURN

WebRTC를 사용하면 P2P 통신을 사용할 수 있지만, 피어 연결을 부트스트랩하기 위해 미디어 및 네트워크 메타데이터를 교환하려면 신호용 서버가 여전히 필요합니다.

WebRTC는 다음과 같은 방법으로 NAT 및 방화벽에 대처합니다.

  • ICE 프레임워크: 피어 간에 가능한 최상의 네트워크 경로를 설정합니다.
  • STUN 서버를 사용하여 각 피어의 공개적으로 액세스 가능한 IP 및 포트를 확인합니다.
  • 직접 연결에 실패하고 데이터 릴레이가 필요한 경우 서버를 TURN합니다.

WebRTC가 서버와 신호 및 네트워킹을 위해 작동하는 방법에 대한 자세한 내용은 실제 WebRTC: STUN, TURN, 신호 전달을 참조하세요.

기능

RTCDataChannel API는 유연한 데이터 유형 집합을 지원합니다. 이 API는 WebSocket을 정확하게 모방하도록 설계되었으며 RTCDataChannel문자열과 함께 자바스크립트의 일부 바이너리 유형(예: Blob, ArrayBuffer, ArrayBufferView)도 지원합니다. 이러한 유형은 파일 전송 및 멀티플레이어 게임 작업에 유용합니다.

RTCDataChannel는 신뢰할 수 없거나 정렬되지 않은 모드 (사용자 데이터그램 프로토콜 또는 UDP와 유사), 신뢰할 수 있고 순서가 지정된 모드 (전송 제어 프로토콜 또는 TCP와 유사), 부분 신뢰할 수 있는 모드에서 작동할 수 있습니다.

  • 안정적이고 순서가 지정된 모드는 메시지 전송뿐만 아니라 전송 순서를 보장합니다. 이로 인해 추가 오버헤드가 발생하므로 모드가 느려질 수 있습니다.
  • 신뢰할 수 없고 정렬되지 않은 모드는 모든 메시지가 다른 쪽으로 전달되거나 메시지가 전달되는 순서를 보장하지 않습니다. 이렇게 하면 오버헤드가 제거되므로 모드가 훨씬 빠르게 작동할 수 있습니다.
  • 부분 신뢰할 수 있는 모드는 재전송 시간 초과 또는 최대 재전송 횟수와 같은 특정 조건에서 메시지 전송을 보장합니다. 메시지 순서도 구성할 수 있습니다.

처음 두 모드의 성능은 패킷 손실이 없을 때 거의 동일합니다. 그러나 신뢰할 수 있고 순서가 지정된 모드에서는 손실된 패킷으로 인해 다른 패킷이 차단되어 재전송 및 도착할 때 손실된 패킷이 비활성 상태가 될 수 있습니다. 물론, 동일한 앱 내에서 각각 안정적인 또는 신뢰할 수 없는 시맨틱을 가진 여러 데이터 채널을 사용할 수도 있습니다.

다음은 일리야 그리고릭고성능 브라우저 네트워킹에서 제공하는 유용한 표입니다.

TCPUDPSCTP
안정성안정성신뢰할 수 없음구성 가능
배달Ordered정렬되지 않음구성 가능
전염바이트 지향메시지 중심메시지 중심
흐름 제어아니요
정체 제어아니요

이제 신뢰할 수 있고 순서가 지정된 모드 또는 신뢰할 수 없는 모드와 정렬되지 않은 모드를 사용하도록 RTCDataChannel를 구성하는 방법을 알아봅니다.

데이터 채널 구성

온라인에서 RTCDataChannel의 몇 가지 간단한 데모를 확인할 수 있습니다.

이 예에서 브라우저가 자체적으로 피어 연결을 만든 다음 데이터 채널을 만들고 피어 연결을 통해 메시지를 보냅니다. 그런 다음 데이터 채널을 만들고 피어 연결을 통해 메시지를 보냅니다. 마지막으로, 메시지는 페이지 반대쪽에 있는 상자에 표시됩니다.

이 작업을 시작하는 코드는 다음과 같이 짧습니다.

const peerConnection = new RTCPeerConnection();

// Establish your peer connection using your signaling channel here
const dataChannel =
  peerConnection.createDataChannel("myLabel", dataChannelOptions);

dataChannel.onerror = (error) => {
  console.log("Data Channel Error:", error);
};

dataChannel.onmessage = (event) => {
  console.log("Got Data Channel Message:", event.data);
};

dataChannel.onopen = () => {
  dataChannel.send("Hello World!");
};

dataChannel.onclose = () => {
  console.log("The Data Channel is Closed");
};

dataChannel 객체는 이미 설정된 피어 연결에서 생성됩니다. 신호가 발생하기 전이나 후에 만들 수 있습니다. 그런 다음 라벨을 전달하여 이 채널을 다른 채널과 구별하고 선택적 구성 설정 집합을 전달합니다.

const dataChannelOptions = {
  ordered: false, // do not guarantee order
  maxPacketLifeTime: 3000, // in milliseconds
};

maxRetransmits 옵션 (실패하기 전에 시도할 횟수)을 추가할 수도 있지만 maxRetransmits 또는 maxPacketLifeTime만 지정할 수 있으며 둘 다 지정할 수는 없습니다. UDP 시맨틱스의 경우 maxRetransmits0로 설정하고 orderedfalse로 설정합니다. 자세한 내용은 IETF RFC: 스트림 제어 전송 프로토콜스트림 제어 전송 프로토콜 부분 안정성 확장을 참고하세요.

  • ordered: 데이터 채널이 순서를 보장해야 하는지 여부
  • maxPacketLifeTime: 실패한 메시지를 재전송할 최대 시간입니다.
  • maxRetransmits: 실패한 메시지를 재전송할 최대 횟수입니다.
  • protocol: 하위 프로토콜을 사용하도록 허용하여 앱에 메타 정보를 제공합니다.
  • negotiated: true로 설정하면 다른 동종 기기에서 데이터 채널의 자동 설정을 삭제하여 다른 쪽에 동일한 ID로 데이터 채널을 만들 수 있는 고유한 방법을 제공합니다.
  • id: true로 설정된 negotiated와 함께 사용해야 하는 채널의 자체 ID를 제공할 수 있습니다.

대부분의 사용자는 처음 세 가지 옵션인 ordered, maxPacketLifeTime, maxRetransmits만 사용하면 됩니다. SCTP (이제 WebRTC를 지원하는 모든 브라우저에서 사용됨)를 사용하면 기본적으로 안정적이고 순서가 지정됩니다. 앱 레이어에서 완전히 제어하려는 경우 신뢰할 수 없고 정렬되지 않은 항목을 사용하는 것이 적합하지만 대부분의 경우 부분적인 안정성이 도움이 됩니다.

WebSocket과 마찬가지로 RTCDataChannel는 연결이 설정되거나 닫히거나 오류가 발생할 때 그리고 다른 피어에서 메시지를 수신할 때 이벤트를 실행합니다.

안전할까?

암호화는 모든 WebRTC 구성요소에 필수입니다. RTCDataChannel를 사용하면 모든 데이터가 데이터그램 전송 계층 보안 (DTLS)으로 보호됩니다. DTLS는 SSL의 파생 제품입니다. 즉, 표준 SSL 기반 연결을 사용하는 것만큼 데이터를 안전하게 보호합니다. DTLS는 표준화되었으며 WebRTC를 지원하는 모든 브라우저에 내장되어 있습니다. 자세한 내용은 Wireshark 위키를 참조하세요.

데이터에 대한 사고 방식 바꾸기

JavaScript에서 대량의 데이터를 처리하는 일은 어려운 일일 수 있습니다. Sharefest 개발자들이 지적했듯이 그러려면 데이터를 새로운 방식으로 생각해야 했습니다. 사용 가능한 메모리 양보다 큰 파일을 전송하는 경우 이 정보를 저장할 새로운 방법을 생각해야 합니다. 아래에서 보시다시피 여기에서 FileSystem API와 같은 기술이 활용됩니다.

파일 공유 앱 빌드

이제 RTCDataChannel를 사용하여 브라우저에서 파일을 공유할 수 있는 웹 앱을 만들 수 있습니다. RTCDataChannel를 기반으로 빌드하면 전송된 파일 데이터가 암호화되며 앱 제공자의 서버에 영향을 미치지 않습니다. 이 기능과 함께 빠른 공유를 위해 여러 클라이언트에 연결할 수 있는 덕분에 WebRTC 파일 공유가 웹에 가장 적합합니다.

이체를 완료하려면 몇 가지 단계를 거쳐야 합니다.

  1. File API를 사용하여 JavaScript로 파일 읽기
  2. RTCPeerConnection로 클라이언트 간에 피어 연결을 설정합니다.
  3. RTCDataChannel를 사용하여 클라이언트 간 데이터 채널을 만듭니다.

RTCDataChannel를 통해 파일을 전송하려고 할 때 고려해야 할 몇 가지 사항이 있습니다.

  • 파일 크기: 파일 크기가 상당히 작고 하나의 Blob으로 저장 및 로드될 수 있는 경우, File API를 사용하여 메모리에 로드한 다음 신뢰할 수 있는 채널을 통해 파일을 그대로 전송할 수 있습니다. 단, 브라우저는 최대 전송 크기에 제한을 적용한다는 점에 유의하세요. 파일 크기가 커질수록 작업이 더 어려워집니다. 단위 분할 메커니즘이 필요한 경우 파일 청크가 로드되어 chunkID 메타데이터와 함께 다른 피어로 전송되어 피어가 인식할 수 있습니다. 이 경우 먼저 파일 시스템 API를 사용하여 청크를 오프라인 스토리지에 저장하고 전체 파일이 있을 때만 사용자의 디스크에 청크를 저장해야 합니다.
  • 청크 크기: 앱의 가장 작은 데이터 '원자'입니다. 현재 전송 크기 제한이 있기 때문에 분할이 필요합니다 (이 문제는 향후 버전의 데이터 채널에서 수정될 예정). 현재 최대 단위 크기는 64KiB로 권장됩니다.

파일이 다른 쪽으로 완전히 전송되면 다음과 같이 앵커 태그를 사용하여 다운로드할 수 있습니다.

function saveFile(blob) {
  const link = document.createElement('a');
  link.href = window.URL.createObjectURL(blob);
  link.download = 'File Name';
  link.click();
};

PubShareGitHub의 이러한 파일 공유 앱은 이 기법을 사용합니다. 둘 다 오픈소스이며 RTCDataChannel을 기반으로 하는 파일 공유 앱에 훌륭한 기반을 제공합니다.

그러면 어떻게 해야 할까요?

RTCDataChannel은(는) 파일 공유, 멀티플레이어 게임, 콘텐츠 전송용 앱을 빌드하는 새로운 방법을 제시합니다.

  • P2P 파일 공유는 앞서 설명한 바와 같이
  • WebGL 등의 다른 기술과 결합된 멀티플레이어 게임(Mozilla의 BananaBread 참조)
  • P2P 데이터 통신을 통해 웹 애셋을 전달하는 프레임워크인 PeerCDN에 의해 개편된 콘텐츠 전송

앱 빌드 방식 변경

이제 RTCDataChannel를 통해 지연 시간이 짧은 고성능 연결을 사용하여 참여도가 높은 앱을 제공할 수 있습니다. PeerJSPubNub WebRTC SDK와 같은 프레임워크를 사용하면 RTCDataChannel를 더 쉽게 구현할 수 있으며, 이제 API는 여러 플랫폼에서 광범위하게 지원됩니다.

RTCDataChannel의 출현으로 브라우저에서 데이터 전송에 대한 사고방식이 바뀔 수 있습니다.

자세히 알아보기