📋 목차
- 서론
- WEB RTC가 뭔데?
- WEB RTC API
- Signaling
- STUN/ TURN SERVER
- 1:N 통신은 어떻게?
- 참고해보기
✍🏻 서론
최근에 WEB RTC 기술에 관심이 많아지면서 간단한 개인 플젝을 해볼까 해서 조금씩 공부해보고 있습니다.
공부하면서 조금씩 정리해 두면 좋을 것 같아 적어둡니다.
👩🏻💻 WEB RTC가 뭔데?
WEB RTC MDN 문서에는 아래와 같이 정의가 되어있습니다.
WebRTC(Web Real-Time Communication)은 웹 애플리케이션과 사이트가 중간자 없이 브라우저 간에 오디오나 영상 미디어를 포착하고 마음대로 스트림할 뿐 아니라, 임의의 데이터도 교환할 수 있도록 하는 기술입니다. WebRTC를 구성하는 일련의 표준들은 플러그인이나 제 3자 소프트웨어 설치 없이 종단 간 데이터 공유와 화상 회의를 가능하게 합니다.
즉, 웹브라우저 상에서 어떤 플러그인 없이 음성채팅은 물론이며 화상채팅, 데이터 교환까지도 가능하게 하는 기술입니다. WEB RTC는 구글에서 VoIP 회사인 GIPS 를 인수한 후, 해당 회사의 음성 / 영상 코덱 및 에코캔슬링 기술을 갖게 되었고, 이 기술을 WebRTC라는 이름으로 2011년 공개했습니다. 현재는 Google Meet 서비스등 다양한 유명한 화상미팅서비스들에 현재 적용되어있는 기술입니다.
👩🏻💻 WEB RTC API
✔️ 서로다른 두기기가 실시간으로 소통하기 위해서는 다음과 같은 사항이 필요합니다.
- 기기의 스트리밍 오디오 / 비디오 / 데이터를 가져올 수 있을 것
- 소통하고자 하는 기기의 IP 주소와 포트 등 네트워크 데이터가 필요하다
- 에러의 보고, 세션의 초기화를 위한 신호 통신을 관리해야한다
- 서로 소통할 수 있는 해상도인지, 코덱은 맞는지 등 capability 정보를 교환해야한다
- 실제로 연결을 맺는다
- 그 이후에 스트리밍 오디오 / 비디오 / 데이터를 주고 받을 수 있어야한다.
✔️ 따라서 스트리밍 데이터를 얻고 통신하기 위해 WebRTC에는 세가지 API가 구현되어 있습니다.
- MediaStream - 카메라/마이크 등 데이터 스트림 접근
- RTCPeerConnection - 암호화 및 대역폭 관리 및 오디오 또는 비디오 연결
- RTCDataChannel - 일반적인 데이터 P2P통신, peer간의 Data를 주고 받을 수 있는 Tunnel API (Websoket과 유사하나, P2P라 속도가 보다 빠름)
WEB RTC가 해주는 역할은 꽤나 큽니다.
그림을 보시면 초록색으로 칠해져있는 부분을 원래는 직접 개발을 해야하는데 이것들을 모두 WEB RTC에서 해줍니다.
👩🏻💻 Signaling
하지만 또 알아야 할 것이 하나 있는데, 바로 Signaling 입니다.
Signaling은 통신을 조율할 메시지를 주고 받는 일련의 과정을 의미합니다.
Signaling 과정은 반드시 스트리밍이 진행하기전에 이루어져야 합니다.
우선 caller와 callee에 대해 설명 드리겠습니다.
- caller? 처음 서버에 연결되어 가상의 공간을 생성하는 PC
- callee? caller가 만든 가상의 공간에 접속하여, 활동하는 PC
✔️ 즉 아래와 같이 역할을 분담한다고 생각하시면 됩니다.
- Signaling을 통해 통신할 peer 간 정보를 교환한다. 네트워크 정보, capability 정보, 세션 수립 등.
- WebRTC를 사용해 연결을 맺고, peer 의 기기에서 미디어를 가져와 교환한다.
✔️ Signaling은 아래와 같은 정보를 교환합니다.
- Session control messages: 통신의 초기화, 종료, 그리고 에러 리포트
- Network configuration : 외부에서 보는 내 컴퓨터의 IP 주소와 포트는 뭐지?
- Media capabilites : 내 브라우저와 상대 브라우저가 사용 가능한 코덱, 그리고 해상도는 뭐지?'
이러한 Signaling은 WEBRTC에서 제공하는 기능이 아니므로, 여러분이 다양하게 선택하시면 되는데 전 node.js 의 soket.io를 선택하였습니다.
Socket.io는 내장된 컨셉인 'rooms'로 인해 WebRTC에 꽤 적합하다고 합니다.
Signaling이 성공적으로 마치게 되면, 이제 pear와 pear끼리 직접 데이터를 주고 받게 됩니다. (아래 내용을 꼭읽어주세요)
👩🏻💻 STUN/ TURN SERVER
시그널링 후, NAT와 방화벽들에 대응하기 위한 ICE의 사용 with STUN/ TURN SERVER
엥? 그럼 이제 직접 데이터를 주고 받는데 왠 서버? 라고 생각하실 수 있습니다.
그림을 보겠습니다.
위와 같이 NAT과 방화벽이 없으면 바로 통신을 하면 되지만, 우리가 살아가고 있는 컴퓨터세상은 아래와 같이 방화벽과 NAT으로 가로막혀있습니다.
WEB RTC는 P2P 통신에 최적화가 되어있습니다. 즉 전통적인 스트리밍 서비스 처럼 클라이언트-서버 구조가 아니라 사용자간의 pear to pear연결을 통해 통신하는 기술 입니다.
이때 peer를 통한 연결이 가능하도록 ICE프레임워크를 사용하는데, P2P 통신 특성상, Peer 간 연결을 위해서 NAT 환경에 대한 고려가 필요합니다.
이렇게 서로간의 연결을 위한 정보를 공유하여 P2P 통신을 가능하게 해주는 것이 Stun/Turn Server입니다.
STUN 서버와 TURN 서버 그리고 ICE
(Simple Traversal of User Datagram Protocol Through Network Address Translators)
STUN은 네트워크 환경에서 Public 관점에서 종단에 Access 가능한 IP:Port를 발견하는 작업입니다.
더욱 쉽게 말하면 사내망 환경해 NAT을 통해 공인 IP, Port를 알아내는 역할을 합니다.
ICE 는 UDP를 통해 기기들을 서로 직접 연결을 시도합니다.
그럴때 아래와 같은 과정을 거칩니다.
- A 클라이언트는 A 클라이언트의 공개주소와 라우터의 NAT 뒤에 있는 클라이언트(peer)가 접근가능한지에 대한 답변을 위한 요청을 STUN서버에 보냅니다.
- STUN서버는 패킷의 IP 헤더와 UDP 헤더의 값(클라이언트의 공인 주소)과 STUN 메시지 안에 있는 STUN 클라이언트의 IP 주소와 UDP 포트 넘버 (클라이언트의 사설 주소)를 비교합니다.
- 그 후 STUN 서버는 두 개의 서로 다른 주소에 대한 바인딩 테이블을 생성해 연결을 맺어줍니다.
그런데 이때 직접(P2P) 연결이 실패할 경우 이제 RTCPeerConnection는 TCP에 의존합니다.
이것도 실패할 경우 TURN서버를 사용합니다.(TURN은 시그널링 데이터가 아니라 피어(Peer)들 사이의 오디오/비디오/데이터 스트리밍 릴레이를 위해 사용됩니다!)
TURN 서버는 net의 제한을 우회합니다.
TURN 서버와 연결을 맺고, 이 서버가 모든 교환 과정을 중개해줍니다.
모든 기기는 TURN 서버로 패킷을 보내고, 서버가 이를 포워딩합니다.
그렇기에 당연히, 오버헤드가 있고, 다른 대안이 없을 때만 사용해야한다고 합니다.
👩🏻💻 1:N통신은 어떻게?
WebRTC는 원래 1대1 상황에서 응용하기 위해 개발되었습니다. 만약 다자간 통신을 지원해야 하는 상황이면,
새로운 아키텍처를 고려해봐야 합니다. 중앙 미디어 서버를 구축할 필요가 있기 때문입니다.
이중 대표적인 아키텍셔로 SFU, MCU가 있습니다.
MCU (Multipoint Control Unit)
한쪽 Peer에 서버를 두고, 들어오는 트래픽을 서버에서 믹싱해서 다시 내보내는 방식입니다. 클라이언트와 네트워크의 부담이 줄어드는 반면, 중앙서버의 컴퓨팅 파워가 많이 요구됩니다. 낡은 기술이고 + 서버 운용 비용이 높아, WebRTC와 같은 실시간성 보장이 우선인 서비스인 경우 장점이 상쇄된다고 합니다.
SFU (Selective Forwarding Unit)
믹싱하지않고 트래픽을 선별적으로 배분해서 보내주는 방식. 각 peer 연결 할당과 encrypt / decrypt 역할을 서버가 담당합니다. 1:N 스트리밍 구조에 적합하다고 합니다.
이번 개인 프로젝트 때는 SFU 아키텍처를 도입하고자 합니다.
⚒️ 참고해보기
https://www.html5rocks.com/ko/tutorials/webrtc/infrastructure/
https://juneyr.dev/webrtc-basics
https://changicho.tistory.com/entry/WebRTC-00-기초
https://alnova2.tistory.com/1110
https://medium.com/pplink/1000명이서-실시간-커뮤니케이션을-하는-가장-효과적인-방법-ca039fbcaedb
'javascript > 사이드 프로젝트' 카테고리의 다른 글
serverless next.js 를 사용해보자! 그리고 자동화까지? (0) | 2022.03.23 |
---|---|
Next.js 에 toast ui Editor 을 같이 사용하는 방법 (짱쉬움) (2) | 2021.04.06 |
ResizeObserver 과 svg Element는 같이 동작하지 않는다. (0) | 2021.03.12 |