(이 글은 juneyr.dev 님의 글을 상당수 참고하였습니다)
별도의 플러그인 없이 실시간 소통이 가능하도록 만들어주는 기술. 기존에는 스카이프, 구글 행아웃을 설치해야 했으나 webRTC를 사용하면 크롬 등의 브라우저에서 바로 실시간 소통을 사용할 수 있음.
WebRTC는 구글이 VoIP 회사인 GIPS를 인수한 후, 해당 회사의 음성 / 영상 코덱 및 에코캔슬링 기술을 갖게 되었음. 이 기술을 WebRTC라는 이름으로 공개한 케이스. 이때가 2011년.
두 기기가 실시간 소통을 하기 위해선 다음과 같은 사항이 필요하다.
이를 위해 WebRTC는 다음 API를 제공함
이는 위 사항의 일부만 만족시키므로, 나머지는 Signaling 이라는 과정으로 관리한다
즉, WebRTC를 사용한 통신은 두 갈래로 설명할 수 있다.
WebRTC는 브라우저 간에 스트리밍 데이터를 교환하기 위해 RTCPeerConnection를 사용한다. 그리고 통신 조정 및 메시지를 컨트롤 하는 메커니즘인 시그널링을 필요로 함. 즉 시그널링은 통신을 조율할 메시지를 주고 받는 일련의 과정을 의미함. 시그널링 표준은 WebRTC 에 정의되어 있지 않으므로 개발자들이 편한 방식을 선택해야 한다.
시그널링의 역할은 다음과 같다.
위 작업은 스트리밍이 시작되기 전에 완료되어야 한다. 구체적으로 살펴보면 아래와 같다.
네트워크 정보 교환 Network configuration
미디어 정보 교환 Media Capabilities
그리고 위에서 말한 Session Control messages는 위 과정에서 필요한 마이너한 과정들을 채워준다.
시그널링을 성공적으로 마치면, 실제 데이터(미디어, 영상, 음성 등)는 P2P 또는 중계서버를 거쳐서 통신하게 된다.
WebRTC에서 왜 서버가 필요한지 의문이 들 수 있다. 하지만 P2P로만 WebRTC 연결을 한다고 해도 서버가 필요한 경우가 있고 이 기술에서 서버는 다음과 같은 역할을 한다.
NAT(Network Address Translation) 은 기기에 공인 IP를 부여하는 기술이다. 라우터에 설정하는데, 라우터는 공인 IP 를 갖고, 라우터에 연결된 모든 기기는 사설 IP 를 갖는다. 기기가 요청할 것이 생기면, 라우터의 고유한 포트를 사용해서 사설 IP 에서 공인 IP 로 변환한다(translation). 어떤 라우터는 접근할 수 있는 노드를 제한 할 수 있다.
ICE 프레임워크가 등장한다. ICE 프레임워크는 기기를 발견하고 연결하기 위한 프레임워크이다.
ICE는 UDP 를 통해 기기들을 서로 직접 연결시도한다.
기기가 NAT 뒤에 있다. STUN 서버가 이를 해결해 줄 수 있겠다.
STUN (Session Traversal Utilities for NAT) 는 기기의 공인 IP 를 알려준다. 기기의 NAT가 직접 연결을 허용하는지, 아닌지 파악하는 역할도 한다.
클라이언트는 STUN 서버에 요청을 보낸다. STUN 서버는 클라이언트의 공인 주소와, 클라이언트가 NAT 뒤에서 접근이 되는지 알려준다.
그 이후에 직접 다른 기기와 통신한다.
1. 🙂 예이! 연결이 되었습니다. 이제 미디어를 교환합시다.
2. 😡 왜 연결이 안되지? TURN 서버가 나설 때 입니다.
어떤 라우터는 Symmetric NAT
를 적용한다.
Symmetric NAT : 목적지에 따라서 같은 private IP 의 노드를 다른 공인 IP 와 포트로 매핑해준다. 이런 경우 라우터는 이전에 연결했던 기기에서의 연결만 허용한다.
WebRTC는 P2P 로 디자인 되어 있음. 그래서 유저들은 가능한 최대한 많은 직접적인 경로에 연결가능함. 실제 사용환경에선 직접 연결이 실패했을 때의 대비책이 필요함. 대비책의 한 과정으로, WebRTC는 STUN 서버를 사용해 컴터의 IP를 가져오고 TURN 서버는 p2p 통신이 실패할 경우 릴레이서버로 동작함.
RTCPeerConnection 은 당사자들 간 데이터를 안정적이고 효율적으로 통신하게 해주는 요소다. 아래 그림에서 초록색 부분은, 원래라면 개발자가 처리해야 부분이다.
원래라면 다음 사항을 직접 해야한다.
WebRTC 컴포넌트에서 암호화는 필수, 그리고 Javascript WebRTC API는 HTTPS 환경에서만 사용할 수 있음. 시그널링 메카니즘은 정의되어 있지 않아서 알아서 보안성있게 잘 짜야됨.
WebRTC는 기본적으로는 P2P, 두 단말이 서로 1:1 통신을 하게 되어있다. 따라서 대규모 방송 서비스를 구축하거나 컨텐츠 가공이 필요할 경우 중앙 미디어 서버를 구축할 필요성이 생긴다. 이런 목적에 따라 SFU, MCU 아키텍처를 고려해볼 수 있다.
중앙 미디어 서버 없이 종단 간 직접 연결하므로, 비용 측면에서 이득이 있다. 다만 peer 수가 증가할수록 개별 기기의 높은 성능을 요구한다. 1:1, 최소한 소규모 미디어 교환에 적합하다.
한쪽 Peer에 서버를 두고, 들어오는 트래픽을 서버에서 믹싱해서 다시 내보내는 방식이다. 클라이언트와 네트워크의 부담이 줄어드는 반면, 중앙서버의 컴퓨팅 파워가 많이 요구된다. 참고한 블로그에서는 낡은 기술이고 + 서버 운용 비용이 높아, WebRTC와 같은 실시간성 보장이 우선인 서비스인 경우 장점이 상쇄된다고 언급되어있다.
믹싱하지않고 트래픽을 선별적으로 배분해서 보내주는 방식. 각 peer 연결 할당과 encrypt / decrypt 역할을 서버가 담당한다. 1:N 스트리밍 구조에 적합하다고 한다.
https://juneyr.dev/webrtc-basics
https://doc-kurento.readthedocs.io/en/6.14.0/tutorials/node/tutorial-one2many.html
https://codelabs.developers.google.com/codelabs/webrtc-web/index.html#4
https://webrtc.ventures/2020/04/the-basics-of-a-webrtc-broadcasting-app/
https://github.com/muaz-khan/WebRTC-Experiment/blob/master/broadcast/broadcast.js