[Javascript] PeerJS 개념 이해하기

Ell!·2022년 2월 21일
1

javascript

목록 보기
4/6

개요

dor.gg 개발을 한지 어언 6개월정도 지났다. 이제 사이트의 기본적인 틀은 (매칭 시스템) 잡힌 것 같아서 '베타 버전'이라는 꼬리표를 떼기 위해 두 개의 큰 산이 남은 상황이다. 그 중 하나가 바로 음성채팅이었는데.

webRTC

peerJS의 사용법을 적기 앞서 그 기반이 되는 개념을 먼저 정리하고 넘어가고자한다.

webRTC의 이해. http와 websocket과 비교

먼저 webRTC라는 단어에 담긴 의미부터 짚고 넘어가보자. RTC는 Real Time Communication의 약자로, web application으로 하여금 어떠한 추가적인 플로그인, 라이브러리없이 오디오, 비디오 등의 stream data를 실시간으로 전송할 수 있게 해주는 기술을 의미한다.

webRTC라는 단어를 처음 듣고 든 생각은 'webSocket'하고 다른 점은 뭔데?'였다. 이렇게 비교해보자.

먼저 간단한 HTTP 통신부터 그림을 통해 살펴보자

간단하게 client와 server가 있고 request와 response로 HTTP 통신을 주고 받는다.

다음은 webSocket이다. (socket.io의 코드를 기준으로 적은 것이다.)

http 통신에 비해 조금 더 복잡해보이지만 그 골조는 같다. client의 요청은 서버를 거쳐 다른 client로 전달된다.

자, 이제부터 본격적인 webRTC의 이야기를 해보려고 한다.

webRTC는 비슷하지만 조금 다르다.

초록색 선이 하나 추가가 되었다. 두 브라우저 사이에서 시그널링(signaling)을 위한 서버가 필요하지만. 일단, 연결이 되고나서는 두 브라우저는 직접적인 통신을 이어나간다.

이것이 바로 webRTC가 Peer-to-Peer 통신이라고 일컬어지는 이유이다.

signaling

webRTC가 연결이 이루어지려면 signaling이라는 작업이 필요하다. 시그널링은 communication 세션이 설정되고, 컨트롤되고, 종료되는 일련의 과정을 의미한다.

이 연결과정에서는 다음 세가지 타입의 정보가 오고간다.

  • session control information : communication session의 시작, 종료, 수정을 담당
  • network data : ip address와 port에 대한 정보 (caller가 callee찾게 도움)
  • media data : determine the codecs and media types that the callers and callees have in common (SDP 포멧에 맞추어서)

** SDP (Session Description Protocol) : 스트리밍 미디어의 초기화 인수를 기술하기 위한 포맷

signaling에는 RTCPeerConnection이라는 API를 통해서 사용자들이 communication하기 위한 환경을 조성해준다. RTCPeerConnection은 host 역할을 위한 network address를 모으는 작업을 해준다.

signaling과 NAT traversal

webRTC를 사용해서 음성, 영상 통화를 하기 위해 기반을 다지는 일은 크게 어렵지 않으나, 현실에서는 넘어야 할 부분이 있다. 각종 방화벽 NAT 기술 등이 이를 어렵게 한다고 한다.

** NAT (Network Address Translation) : 사설 IP 주소와 공인 IP 주소 간의 상호 변환 기술. 회사에서는 보안을 이유로 외부에서 접속 불가능한 사설 IP를 사용하는데 그러한 데에 쓰는 기술으로 보면 될 듯하다.

그렇다면 webRTC는 어떻게 다른 peer의 IP 주소를 찾아낼 수 있을까? webRTC는 ICE라고 하는 방법을 사용한다.

ICE는 Interactive Connectivity Establishment의 약자로, 두 단말이 서로 통신할 수 있는 최적의 경로를 찾을 수 있도록 도와주는 프레임워크이다.

ICE는 STUN과 TURN을 사용하는 프레임워크로, STUN은 단말이 자신의 공인 IP 주소와 포트를 확인하는 과정에 대한 프로토콜이고, TURN은 단말이 패킷을 릴레이 시켜 줄 서버를 확인하는 과정에 대한 프로토콜이다.

결론적으로 일련의 과정을 통해 통신 가능한 IP 주소를 찾게 되는 것이다. (ICE는 우선적으로 STUN 서버를 사용하고 실패하면 TURN을 사용한다고 한다. 어찌됫건 결론적으로 IP 주소를 찾는 과정임은 같다.)

webRTC API

webRTC의 기본적인 원리는 어느정도 소개한 것 같다. 마지막으로 webRTC를 이루는 3가지의 API를 간략하게 소개하려고 한다.

getUserMedia

camera, screen에 대한 접근 권한을 access 한다.

PeerConnection

모든 작업이 PeerConnection을 거쳐 이루어진다고 한다. 인코딩, 디코딩, network로 전송, NAT traversal care 등등

DataChannel

브라우저 사이의 arbitraty data 전달 이런 작업을 할 수 있다고 한다.

PeerJS

돌고 돌아 원래 다루고자 했던 내용에 다시 돌아왔다. peerJS는 webRTC를 쉽게 사용하기 위한 라이브러리이다. webSocket을 쉽게 사용하기 위한 socket.io같은 사이라고 할 수 있으려나.

var peer = new Peer();

peer 객체를 생성해준다.

peer.on('open', function(id) {
  console.log('My peer ID is: ' + id);
});

각 peer 객체는 생성될 때, 고유의 unique id를 가지고 만들어진다. 다른 peer와 연결하기 위해서는 그 유저의 peerID를 알아야 한다.

var peer = new Peer([id])

위의 방식을 통해 직접 id를 정해줄 수 있다. 우리 사이트의 경우 각 유저의 uniqueID를 crypto js를 사용해 일련 번호를 만들어 사용하였다.

이제 여기서부터 두 가지 파트로 나뉘어진다.

start call

 navigator.mediaDevices.getUserMedia({video:false, audio:true}).then((mediaStream) => {
 	// Call a peer, providing our mediaStream
	var call = peer.call('dest-peer-id', mediaStream); // 1 걸기
   
   call.on('stream', function(stream) { //4. 받은 것 작업
     // `stream` is the MediaStream of the remote peer.
     // Here you'd add it to an HTML video/canvas element.
   });
 })

통화를 거는 부분이다. 다른 사람의 peer id가 필요하다. 여러명이라면 forEach를 사용해서 걸어줄 수 있을 것이다.

answer call

const userMedia = navigator.mediaDevices.getUserMedia({
  video: false,
  audio: true,
});


peer.on('call', function(call) { //2 받기
  userMedia.then(mediaStream => {
  // Answer the call, providing our mediaStream
  call.answer(mediaStream); // 3 답장하고
  call.on('stream', function(stream) { // 2-1. 받은거 작업
    // `stream` is the MediaStream of the remote peer.
    // Here you'd add it to an HTML video/canvas element.
  });
});


참고

what is webRTC

what is webRTC signaling

webRTC란?

NAT traversal

ICE, STUN, TURN

peerJS 작동 순서

profile
더 나은 서비스를 고민하는 프론트엔드 개발자.

0개의 댓글