본문 바로가기
항해

WebRTC에 대한 이해

by ho-bolt 2022. 6. 9.

목차 :

  • WebRTC란 뭘까?
  • WebRTC 클래스
  • Signaling server
  • RTCPeerConnection
  • RTCPeerConnection plus servers
  • 코드 분석
  • WebRTC 용어 정리

WebRTC란 뭘까??

: WebRTC(Web Real-Time Commnication)는 웹 어플리케이션 간에 프로그인 ( 별도의 소프트웨어) 의 도움 없이도 서로 통신할 수 있도록 설계된 API이다. 웹 브라우저 기반의 통신 방식으로 음성 통화, 영상 통화 P2P 파일 공유 등으로 활용할 수 있다.

[출처 : 위키백과]


구성 요소

WebRTC의 주요 구성요소는 자바스크립트 API를 포함하고 있다.

  1. getUserMedia : 오디오와 비디오 미디어를 가지고 온다 ( 이용자의 마이크, 카메라에 접근하는 것 )
  2. RTCPeerConnection : 피어간 오디오, 비디오 통신을 활성화 시킨다. 신호 처리, 코덱 관리, P2P 통신 보안 대역폭 관리를 수행한다.
  3. RTCDataChannel : 피어간 양방향 임의 데이터 통신을 허용한다. 웹 소켓과 동일한 API를 사용한다.

WebRTC 클래스

P2P : Peer to Peer의 줄인말이다. 중앙 서버를 거치지 않고 클라이언트 컴퓨터끼리 직접 통신하는 방식이다. 일반적으로 컴퓨터의 쌍방향 파일 전송 시스템을 일컫지만 P2P라고 해서 꼭 파일 전송에 사용되는 것은 아니다. 중앙 서버 없이 컴퓨터와 컴퓨터간에 연결을 해주고 프로그램 엔진만 만들면 되서 간편하게 파일을 전송할 수 있다.

[출처 : https://velog.io/@yyong3519/WebRTC-%EA%B0%9C%EB%85%90]

  • WebRTC 기술은 P2P 통신에 최적화 되어있다.
  • 위의 3가지 구성요소에 의해서 실시간 데이터 교환이 발생한다.
    • MediaStream ( getUserMedia) :마이크/카메라 데이터 스트림에 접근
    • RTCPeerConnection : 암호화 및 대역폭 관리 및 오디오/비디오 연결
    • RTCDataChannel :일반적인 데이터 P2P 통신

위에서 말한 3가지 객체를 통해서 데이터 교환이 이루어지며 RTCPeerConnection들이 적절하게 데이터를 교환할 수 있게 처리하는 과정을 시그널링(Signaling)이라고 말한다.

PeerConnection은 2명의 유저가 스트름을 주고 받는 것으로 연결을 요청한 콜러(Caller)와 연결을 받는 (Callee)가 존재한다.

이 콜러와 콜리가 통신을 하기 위해선 중간 역할을 하는 매개자(서버)가 필요하고 이 서버를 통해서 SessionDescription을 각자 주고 받아야 한다.


SIGNALING SERVER

session control, network, and media information

  • WebRTC 브라우저들 사이에 스트리밍 데이터를 주고 받는 RTCPeerConnection을 사용한다.
  • 통신을 조율하고 조장할 메시지를 주고 받기 위해서 Signaling 과정이 필요하다
  • Singaling은 RTCPeerConnection API에 포함되지 않는다.

Signaling은 3가지의 종류와 정보를 교환합니다

  1. Session control messages: 통신의 초기화, 종료 에러리포트를 위해서
  2. Network configuration : 외부 세상으로 내 컴퓨터의 ip주소와 port는 어떻게 되지?
  3. Media capabilites: 내 브라우저와 상대 브라우저가 사용 가능한 코덱들과 해상도들은 어떻게 되지?

이 3가지 정보 교환은 P2P 스트리밍이 시작되기 전에 성공적으로 완료가 되어야 한다.

예시로 A와 B가 통신하기를 원한다고 가정한다. Signaling과정을 보여주는 WebRTC W3C Working Draft 에 따라 예제코드는 아래와 같다. 이 코드는 이미 특정 Signaling 방식이 존재한다고 가정하고 createSignalingChannel()함수를 만들었다. 또한 Chrome과 Opera에선 RTCPeerConnection가 prefix를 가지고 있다는 점을 유의해야 한다.

var signalingChannel = createSignalingChannel();
var pc;
var configuration = ...;

// run start(true) to initiate a call
function start(isCaller) {
    pc = new RTCPeerConnection(configuration);

    // send any ice candidates to the other peer
    pc.onicecandidate = function (evt) {
        signalingChannel.send(JSON.stringify({ "candidate": evt.candidate }));
    };

    // once remote stream arrives, show it in the remote video element
    pc.onaddstream = function (evt) {
        remoteView.src = URL.createObjectURL(evt.stream);
    };

    // get the local stream, show it in the local video element and send it
    navigator.getUserMedia({ "audio": true, "video": true }, function (stream) {
        selfView.src = URL.createObjectURL(stream);
        pc.addStream(stream);

        if (isCaller)
            pc.createOffer(gotDescription);
        else
            pc.createAnswer(pc.remoteDescription, gotDescription);

        function gotDescription(desc) {
            pc.setLocalDescription(desc);
            signalingChannel.send(JSON.stringify({ "sdp": desc }));
        }
    });
}

signalingChannel.onmessage = function (evt) {
    if (!pc)
        start(false);

    var signal = JSON.parse(evt.data);
    if (signal.sdp)
        pc.setRemoteDescription(new RTCSessionDescription(signal.sdp));
    else
        pc.addIceCandidate(new RTCIceCandidate(signal.candidate));
};

가장 먼저 A와 B는 네트워크 정보를 교환한다. (finding candidates) 란 표현은 ICE framework를 사용해서 넽워크 인터페이스와 포트를 찾는 과정을 뜻한다.

1. A가 onicecandidate 핸들러를 가진 RTCPeerConnection Object를 생성한다.

2. 핸들러는 네트워크 candidates가 가능해지면 실행된다

3. A가 serializedcandidate data를 WebSocket 또는 어떤 특정 방식, 자신만의 Signaling 채널을 통해 B에게 전송한다

4. B가 A로부터 candidate 메세지를 받으면 B는 peer description을 위한 candidate를 추가하기 위해서 addIceCandidate를 호출한다.

상세 순서 과정

(피어) WebRTC 클라이언트들은 해상도와 코덱 기능같은 미디어 정보들을 서로 교환하고 확인해야 한다.

미디어 정보의 교환을 위한 SignlingSession Description Protocol(SDP)를 사용하는 offer와 answer를 통해서 진행된다.

1. A가 RTCPeerConnectioncreateOffer()함수를 호출한다. 이 함수의 인자로 입력된 callback을 통해 A의 Session Description 정보를 나타내는 RTCPeerSessionDescription을 얻는다.

2. callback 안에서 A는 자신의 descriptionsetLocalDescription()함수로 설정하고 이 session descriptionsignaling 채널을 통해 B에게 전달한다. ( setLocalDescription()가 호출되기 전까지는 candidates수집이 시작되지 않는다!!)

3. B는 A가 보낸 session description정보를 setRemoteDescription()함수를 통해 설정한다.

4. B는 RTCPeerConnectioncreateAnswer() 함수에 A로부터 받은 remote description을 전달하고 실행한다. 그러면 A의 정보를 기반으로 Local Session이 생성된다. 그 다음 createAnswer()의 callback은 RTCSessionDescription을 전달해준다.**( B는 이것을 local description 으로 설정하고 A에게 전달한다. )**

5. A가 B의 Session description을 받으면 setRemoteDescription을 이용해 remote description으로 설정한다.

RTCSessionDescription객체들은 Session Description Protocal , SDP를 따르는 blob이다. 직렬화된 SDP 객체는 다음과 같이 보인다.

v=0
o=- 3883943731 1 IN IP4 127.0.0.1
s=
t=0 0
a=group:BUNDLE audio video
m=audio 1 RTP/SAVPF 103 104 0 8 106 105 13 126

// ...

a=ssrc:2223794119 label:H4fjnMzxy3dPIgQ7HxuCTLb4wLLLeRHnFxh810

여기서 명심 할것 !

네트워크 미디어 정보의 교환과 획득은 반드시 동시에 완료된다는 것!

하지만 이 두 가지 과정들은 피어간의 오디오/비디오 스트리밍 시작전에 반드시 완료되어야 한다는 것 !!!!!

출처:https://www.html5rocks.com/ko/tutorials/webrtc/basics/

[Get Started with WebRTC - HTML5 Rocks

WebRTC provides plugin-free, real-time communication for video, audio and data.

www.html5rocks.com](https://www.html5rocks.com/ko/tutorials/webrtc/basics/)

이렇게 Signaling과정이 끝나면 data는 peer와 peer끼리 또는 송신자와 수신자가 직접 주고 받게 된다. ( 스트리밍이 RTCPeerConnection의 역할이다 )


RTCPeerConnection

RTCPeerConnection은 Peer들 간의 데이터를 안정적이고 효율적으로 통신하게 처리하는 WebRTC 컴포넌트이다.

출처:https://www.html5rocks.com/ko/tutorials/webrtc/basics/

[Get Started with WebRTC - HTML5 Rocks

WebRTC provides plugin-free, real-time communication for video, audio and data.

www.html5rocks.com](https://www.html5rocks.com/ko/tutorials/webrtc/basics/)


RTCPeerConnection plus Server

WebRTC를 사용하기 위해서는 여러가지 데이터들이 교환되어야 한다.

  • 사용자들은 상대방을 발견하고 이름과 같은 현실세계의 상세를 교환한다.
  • WebRTC 클라이언트 어플리케이션들(피어들) 은 네트워크 정보를 교환한다.
  • 피어들은 비디오 포맷과 해상도 같은 미디어에 관한 데이터를 교환한다.
  • WebRTC 클라이언트 어플리케이션들을 NAT gateways와 방화벽을 넘나든다.

즉 WebRTC는 4가지 종류의 서버 측 기능들이 필요하다

  • 사용자 탐색과 통신
  • Signaling
  • NAT/firewall 탐색
  • P2P 실패 했을 때의 중계서버들

STUN 프로토콜과 그 확장인 TURN은 NAT 탐색과 다른 네트워크 문제들을 처리하기 위해 RTCPeerConnection을 사용 가능하게 하는 ICE framework를 사용한다.

ICE framework: 비디오 채팅 클라이언트 같은 피어들을 연결하기 위한 프레임워크이다.

우선 ICE는 가장 대기시간이 적은 UDP를 통해 피어들끼리 직접 연결 가능한지 시도한다. 여기서 STUN 서버들은 한 가지 일을 한다. NAT 뒤에 있는 피어들이 연결 가능하도록 자신들의 공용 주소와 포트를 찾아준다.


RTCPeerConnection : making a call

function createPeerConnection() {
  var pc_config = {"iceServers": [{"url": "stun:stun.l.google.com:19302"}]};
  try {
    // Create an RTCPeerConnection via the polyfill (adapter.js).
    pc = new RTCPeerConnection(pc_config);
    pc.onicecandidate = onIceCandidate;
    console.log("Created RTCPeerConnnection with config:\n" + "  \"" +
      JSON.stringify(pc_config) + "\".");
  } catch (e) {
    console.log("Failed to create PeerConnection, exception: " + e.message);
    alert("Cannot create RTCPeerConnection object; WebRTC is not supported by this browser.");
      return;
  }

  pc.onconnecting = onSessionConnecting;
  pc.onopen = onSessionOpened;
  pc.onaddstream = onRemoteStreamAdded;
  pc.onremovestream = onRemoteStreamRemoved;
}
  • onIceCandidate() 콜백을 통해 STUN 서버를 사용한 연결을 설정하기 위한 것
  • 핸들러들은 RTCPeerConnection 에서 발생하는 이벤트들을 위해 설ㅈ어된다.
  • 세션이 연결되고 열렸을 대 그리고 원격 스트림이 추가되고 삭제되었을 때
  • 사실 이 예제에서의 핸들러들은 단순히 로그 메세지만 출력하고 있습니다.(remoteVideo의 소스를 설정하는 onRemoteStreamAdded()만 제외하고)
function onRemoteStreamAdded(event) {
  // ...
  miniVideo.src = localVideo.src;
  attachMediaStream(remoteVideo, event.stream);
  remoteStream = event.stream;
  waitForRemoteVideo();
}

maybeStart()에서 createPeerConnection() 이 한 번 호출이 되면 연결이 생성되오 callee에게 전달이 된다.

function doCall() {
  console.log("Sending offer to peer.");
  pc.createOffer(setLocalAndSendMessage, null, mediaConstraints);
}

추가적으로 offer를 위해 serialized 된 SessionDescription을 원격 피어에게 메세지를 전달한다. 이 과정은 setLocalAndSendMessage()를 통해 진행된다.

function setLocalAndSendMessage(sessionDescription) {
  // Set Opus as the preferred codec in SDP if Opus is present.
  sessionDescription.sdp = preferOpus(sessionDescription.sdp);
  pc.setLocalDescription(sessionDescription);
  sendMessage(sessionDescription);
}

WebRTC 용어 정리

STUN Server, TURN Server

WebRTC는 P2P에 최적화 되어있다. 즉 피어들간의 공인 네트워크 주소(IP) 를 알아야지 데이터를 교환할 수 있는 데 실제 개인 컴퓨터는 방화벽과 같은 보호장치들에 의해 보호되어 있다. 그래서 피어간 연결이 쉽지 가 않다. 하지만 서로 간의 연결을 위한 정보를 공유하여 P2P 통신을 가능하게 해주는 것이 STUN/TURN Server.이다.

=> stun과 turn 서버에 대해 더 알아보고 싶다면 https://alnova2.tistory.com/1110 참고!!

 

SDP (Session Description Protocol)

세션 기술 프로토콜은 스트리밍 미디어의 초기화 argument를 기술하기 위한 포맷이다. 실제로 WebRTC는 SDP format에 맞춰 음성, 영상 데이터를 교환하고 있다. Peer 서로간의 미디어와 네트워크에 관한 정보를 이해하기 위해 사용된다. 

 

ICE (Interactive Connectivity Establishment)

NAT 환경에서 자신의 공인 IP주소를 파악하고 상대방에게 데이터를 전송하기 위한 PEER 간의 응답 프로토콜로 일반적으로 STUN/TURN 서버를 이용해서 구축 한다.

쉽게 말하자면 한 쪽 피어에서 Offer를 보내면 다른 피어가 Answer함으로써 피어간 연결이 설정된다.

참고:

https://velog.io/@yyong3519/WebRTC-%EA%B0%9C%EB%85%90:https://www.html5rocks.com/ko/tutorials/webrtc/basics/

[WebRTC 개념 velog.io](https://velog.io/@yyong3519/WebRTC-%EA%B0%9C%EB%85%90)

728x90

'항해' 카테고리의 다른 글

WebRTC 코드로 적용해보기  (0) 2022.06.09
핸드폰 번호 하이픈형식으로 출력되는 문제 영상  (2) 2022.03.17
알고리즘 3  (0) 2022.03.17
알고리즘 2  (0) 2022.03.14
알고리즘 문제  (0) 2022.03.14

댓글