코딩 교육 플랫폼이라는 주제의 프로젝트를 진행하면서 WebRtc 기술을 사용해보게 되었다.
라이브 스트리밍을 통해 방송을 켜고, 시청자가 입장해서 실시간 방송을 볼 수 있도록 구현해야 했는데, 이 때 필요했던 개념들을 정리해보려고 한다.
WebRTC(Web Real-Time Communications)란, 웹 어플리케이션(Android 도 지원) 및 사이트들이 별도의 소프트웨어 없이 음성, 영상 미디어 혹은 텍스트, 파일 같은 데이터를 브라우져끼리 주고 받을 수 있게 만든 기술이다.
즉, 영상 통화나 실시간 방송 같은 기능을 별도의 서버 없이 구현할 수 있다.
처음에는 P2P 통신만으로 방송 기능이 모두 해결될 줄 알았지만... 그건 1:1 영상 통화 같은 기능에서만 가능한 부분이었다.
내 목표는 여러 방송자가 방송을 켤 수 있고, 여러 시청자들이 각 방송에 입장할 수 있도록 하는 것이었기 때문에 다른 방법을 찾아보았고, 중간 서버(시그널링 서버)를 두면 해결할 수 있다는 정보를 찾았다.
간단히 말하면 방송자 <-> 시그널링 서버 <-> 시청자 형태로 서로 간의 정보를 주고 받아 Socket 연결을 시도하는 것!
하지만, 이렇게 하면 1:n 방송은 가능하나 n:n 방송이 불가능하여 다시 검색을 시작하였다...
그렇게 찾은 방법이 미디어 서버이다. 방송자와 시청자간의 중간 서버를 하나 더 두어서 방송자의 정보를 여러 시청자에게 전달할 수 있는 파이프라인을 만든다고 생각하면 된다.
즉, 방송자가 방송을 시작하면 하나의 방송 파이프라인이 생성되고, 시청자가 입장하면 시청자마다 파이프라인을 생성한 후 방송 파이프라인에 연결하면 비로소 방송을 시청할 수 있다!
자, 이렇게 대략적인 구성 정보를 계획하고 시작해보려고 했으나... 또 다른 문제가 발생하였다.
바로 공유기와 같은 NAT 환경에서는 직접적인 연결이 불가능하다는 것이었다.
이를 해결하기 위해 Stun 서버와 Turn 서버를 사용한다고 하여 개념을 살펴보았다.
공유기 같이 중간에 방화벽이 놓여있는 NAT 환경에서는 직접적인 P2P 통신이 불가능하다.
즉, 192.xxx.xxx.xxx 처럼 Private IP를 사용하는 곳에서는 직접적으로 통신을 할 수 없다는 이야기이다.
그렇다면 Public IP를 알아내야 하는데, 이 때 사용하는 것이 Stun 서버이다.
Stun 서버는 Session Traversal Utilities for NAT의 약자로 사용자의 외부 IP 정보를 알려주는 역할을 한다.
아래와 같이 외부 IP 정보를 받아와서 직접적인 P2P 연결을 시도하도록 하는 기능을 한다.
하지만, Stun 서버는 Peer 간의 직접적인 연결 시도 시 사용하므로 Turn 서버를 살펴보았다.
Turn는 Traversal Using Relays around NAT의 약자로 모든 정보를 Turn 서버에 보냄으로써 정보 전달 시 Turn 서버를 중간 다리 역할로 사용할 수 있도록 한다.
나의 경우에는 이미 시그널링 서버와 미디어 서버를 사용하기로 하였으므로 직접적인 P2P 연결을 할 필요가 없기 때문에 Turn 서버를 사용하기로 결정하였다!
이렇게 여러 방황을 끝으로 설계한 결과 아래와 같이 설계를 하였다.
Android : Google WebRtc
Cloud : Azure (Ubuntu)
Signaling Server : Express + Nodejs
Media Server : Kurento
Turn Server : Coturn