통신, 게임 또는 파일 전송을 위해 두 브라우저 간에 데이터를 전송하는 작업은 다소 복잡할 수 있습니다. 데이터를 중계하기 위해 서버를 설정하고 이에 대한 비용을 지불하고 이를 여러 데이터 센터로 확장하는 것이 필요합니다. 이 시나리오에서는 지연 시간이 길어질 수 있으며 데이터를 비공개로 유지하기가 어렵습니다.
이러한 문제는 WebRTC의 RTCDataChannel
API를 사용하여 한 피어에서 다른 피어로 직접 데이터를 전송하면 완화할 수 있습니다. 이 도움말에서는 데이터 채널을 설정하고 사용하는 방법의 기본사항과 현재 웹에서 일반적으로 사용되는 사용 사례를 다룹니다.
다른 데이터 채널을 사용하는 이유는 무엇인가요?
WebSocket, AJAX, 서버 전송 이벤트가 있습니다. 다른 커뮤니케이션 채널이 필요한 이유는 무엇인가요? WebSocket은 양방향이지만 이러한 모든 기술은 서버와의 통신을 위해 설계되었습니다.
RTCDataChannel
는 다른 접근 방식을 취합니다.
RTCPeerConnection
API와 호환되며 이 API는 피어 투 피어 연결을 지원합니다. 따라서 중간 서버가 없고 '홉'이 적어 지연 시간이 짧아질 수 있습니다.RTCDataChannel
는 스트림 제어 전송 프로토콜(SCTP)을 사용하여 구성 가능한 전송 시맨틱스-순서가 지정되지 않은 전송 및 재전송 구성을 허용합니다.
이제 Google Chrome, Opera, Firefox의 데스크톱 및 Android에서 SCTP 지원과 함께 RTCDataChannel
를 사용할 수 있습니다.
주의사항: 신호 전달, STUN, TURN
WebRTC는 P2P 통신을 가능하게 하지만, 피어 연결을 부트스트랩하기 위해 미디어 및 네트워크 메타데이터를 교환하기 위한 신호용 서버가 필요합니다.
WebRTC는 다음을 사용하여 NAT 및 방화벽을 처리합니다.
- 피어 간에 가능한 한 최적의 네트워크 경로를 설정하는 ICE 프레임워크
- STUN 서버: 각 피어의 공개적으로 액세스 가능한 IP 및 포트를 확인합니다.
- 직접 연결에 실패하고 데이터 릴레이가 필요한 경우 TURN 서버
WebRTC가 신호 전달 및 네트워킹을 위해 서버와 상호작용하는 방식에 관한 자세한 내용은 실제 환경의 WebRTC: STUN, TURN, 신호 전달을 참고하세요.
기능
RTCDataChannel
API는 유연한 데이터 유형 집합을 지원합니다. 이 API는 WebSocket을 정확하게 모방하도록 설계되었으며 RTCDataChannel
는 문자열과 JavaScript의 일부 바이너리 유형(예: Blob, ArrayBuffer, ArrayBufferView)을 지원합니다. 이러한 유형은 파일 전송 및 멀티플레이어 게임 사용 시 유용할 수 있습니다.
RTCDataChannel
은 비신뢰할 수 있고 순서가 없는 모드 (사용자 데이터그램 프로토콜 또는 UDP와 유사), 신뢰할 수 있고 순서가 있는 모드 (전송 제어 프로토콜 또는 TCP와 유사), 부분적으로 신뢰할 수 있는 모드에서 작동할 수 있습니다.
- 안정적이고 순서가 지정된 모드는 메시지 전송과 메시지 전송 순서를 보장합니다. 이렇게 하면 오버헤드가 추가되어 이 모드가 느려질 수 있습니다.
- 비신뢰할 수 있고 순서가 없는 모드는 모든 메시지가 상대방에게 전송되거나 어떤 순서로 전송되는지 보장하지 않습니다. 이렇게 하면 오버헤드가 제거되어 이 모드가 훨씬 더 빠르게 작동합니다.
- 부분 신뢰할 수 있는 모드는 재전송 시간 제한 또는 최대 재전송 횟수와 같은 특정 조건에서 메시지 전송을 보장합니다. 메시지 순서도 구성할 수 있습니다.
패킷 손실이 없으면 처음 두 모드의 성능은 거의 비슷합니다. 그러나 신뢰할 수 있고 순서가 지정된 모드에서 손실된 패킷은 다른 패킷이 뒤에서 차단되며 손실된 패킷은 재전송되어 도착할 때까지 비활성 상태일 수 있습니다. 물론 동일한 앱 내에서 각각 신뢰할 수 있거나 신뢰할 수 없는 시맨틱을 사용하는 여러 데이터 채널을 사용할 수 있습니다.
다음은 Ilya Grigorik의 High Performance Browser Networking 표입니다.
TCP | UDP | SCTP | |
안정성 | 안정성 | 신뢰할 수 없음 | 구성 가능 |
배달 | 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 시맨틱의 경우 maxRetransmits
를 0
로, ordered
를 false
로 설정합니다. 자세한 내용은 IETF RFC: 스트림 제어 전송 프로토콜 및 스트림 제어 전송 프로토콜 부분 안정성 확장을 참고하세요.
ordered
: 데이터 채널에서 순서를 보장해야 하는지 여부입니다.maxPacketLifeTime
: 실패한 메시지를 재전송하려고 시도하는 최대 시간입니다.maxRetransmits
: 실패한 메시지를 재전송하려고 시도하는 최대 횟수입니다.protocol
: 앱에 메타 정보를 제공하는 하위 프로토콜을 사용할 수 있습니다.negotiated
: true로 설정하면 다른 피어에서 데이터 채널의 자동 설정이 삭제되므로 다른 쪽에서 동일한 ID로 데이터 채널을 만드는 자체 방법을 제공할 수 있습니다.id
:true
로 설정된negotiated
와 함께 사용해야만 사용할 수 있는 채널의 자체 ID를 제공할 수 있습니다.
대부분의 사용자는 처음 세 가지 옵션인 ordered
, maxPacketLifeTime
, maxRetransmits
만 사용하면 됩니다. SCTP (현재 WebRTC를 지원하는 모든 브라우저에서 사용)를 사용하면 안정적이고 순서가 지정된 것이 기본적으로 true입니다. 앱 레이어에서 전체를 제어하려면 안정적이지 않고 순서가 없는 방식을 사용하는 것이 좋지만 대부분의 경우 부분적인 안정성이 도움이 됩니다.
WebSocket과 마찬가지로 RTCDataChannel
는 연결이 설정되거나 닫히거나 오류가 발생할 때, 그리고 다른 피어로부터 메시지를 수신할 때 이벤트를 실행합니다.
안전할까?
암호화는 모든 WebRTC 구성요소에 필수입니다. RTCDataChannel
를 사용하면 모든 데이터가 데이터그램 전송 계층 보안 (DTLS)으로 보호됩니다. DTLS는 SSL에서 파생된 것으로, 표준 SSL 기반 연결을 사용하는 경우만큼 데이터 보안이 유지됩니다. DTLS는 표준화되어 있으며 WebRTC를 지원하는 모든 브라우저에 내장되어 있습니다. 자세한 내용은 Wireshark 위키를 참조하세요.
데이터에 대한 생각 바꾸기
JavaScript에서는 대량의 데이터를 처리하는 것이 골칫거리가 될 수 있습니다. Sharefest의 개발자가 지적했듯이 이를 위해서는 데이터에 대해 새로운 방식으로 생각해야 했습니다. 사용 가능한 메모리보다 큰 파일을 전송하는 경우 이 정보를 저장하는 새로운 방법을 생각해 보아야 합니다. 다음과 같이 FileSystem API와 같은 기술이 여기에 사용됩니다.
파일 공유 앱 빌드
이제 RTCDataChannel
를 사용하여 브라우저에서 파일을 공유할 수 있는 웹 앱을 만들 수 있습니다. RTCDataChannel
를 기반으로 빌드하면 전송된 파일 데이터가 암호화되고 앱 제공자의 서버와 영향을 받지 않습니다. 이 기능은 더 빠른 공유를 위해 여러 클라이언트에 연결할 수 있는 가능성과 결합되어 WebRTC 파일 공유를 웹에 적합한 후보로 만듭니다.
이전을 완료하려면 다음 단계를 따라야 합니다.
- File API를 사용하여 JavaScript에서 파일을 읽습니다.
RTCPeerConnection
를 사용하여 클라이언트 간에 피어 연결을 만듭니다.RTCDataChannel
를 사용하여 클라이언트 간에 데이터 채널을 만듭니다.
RTCDataChannel
를 통해 파일을 전송하려고 할 때는 다음 사항을 고려해야 합니다.
- 파일 크기: 파일 크기가 상당히 작고 하나의 blob으로 저장 및 로드할 수 있는 경우 File API를 사용하여 메모리에 로드한 다음 안정적인 채널을 통해 파일을 있는 그대로 전송할 수 있습니다(단, 브라우저는 최대 전송 크기에 제한을 적용함). 파일 크기가 커질수록 작업이 어려워집니다. 청킹 메커니즘이 필요한 경우 파일 청크가 로드되어 피어가 인식할 수 있도록
chunkID
메타데이터와 함께 다른 피어로 전송됩니다. 이 경우 먼저 청크를 오프라인 저장소(예: FileSystem API 사용)에 저장하고 파일이 전체적으로 있으면 사용자의 디스크에 저장해야 합니다. - 청크 크기: 앱의 가장 작은 데이터 '원자'입니다. 현재 전송 크기 제한이 있으므로 청크 처리가 필요합니다(향후 버전의 데이터 채널에서 수정될 예정). 현재 최대 청크 크기에 관한 권장사항은 64KiB입니다.
파일이 다른 쪽으로 완전히 전송되면 앵커 태그를 사용하여 파일을 다운로드할 수 있습니다.
function saveFile(blob) {
const link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = 'File Name';
link.click();
};
PubShare 및 GitHub의 이러한 파일 공유 앱은 이 기법을 사용합니다. 두 프로젝트 모두 오픈소스이며 RTCDataChannel
를 기반으로 하는 파일 공유 앱에 적합한 기반을 제공합니다.
그러면 어떻게 해야 할까요?
RTCDataChannel
를 사용하면 파일 공유, 멀티플레이어 게임, 콘텐츠 전송을 위한 앱을 빌드하는 새로운 방법을 사용할 수 있습니다.
- 앞에서 설명한 P2P 파일 공유
- Mozilla의 BananaBread에서 볼 수 있듯이 WebGL과 같은 다른 기술과 결합된 멀티플레이어 게임
- P2P 데이터 통신을 통해 웹 애셋을 전송하는 프레임워크인 PeerCDN으로 재창조된 콘텐츠 전송
앱 빌드 방식 변경
이제 RTCDataChannel
를 통해 고성능, 지연 시간이 짧은 연결을 사용하여 더 몰입도 높은 앱을 제공할 수 있습니다. PeerJS 및 PubNub WebRTC SDK와 같은 프레임워크를 사용하면 RTCDataChannel
를 더 쉽게 구현할 수 있으며 이제 API는 다양한 플랫폼에서 광범위하게 지원됩니다.
RTCDataChannel
의 등장으로 브라우저에서 데이터 전송을 생각하는 방식이 달라질 수 있습니다.