
개발 블로그의 첫 장을 webRTC를 주제로 쓰게 될 줄은 몰랐다. 이번에 진행하는 프로젝트에서 영상통화 어플을 만들기 위해서 webRTC를 사용하게 됐는데 처음 사용하는 기능이고 아직 잘 몰라서 정리도 할 겸 써본다.
MDN에 따르면 "웹 애플리케이션과 사이트가 중간자 없이 브라우저 간에 오디오나 영상 미디어를 포착하고 마음대로 스트림할 뿐 아니라, 임의의 데이터도 교환할 수 있도록 하는 기술" 이라고 나와있다.
다양한 글들을 읽고 이해한 바로는 서버를 거치지 않고 브라우저간 연결을 통해 peer to peer(p2p)로 데이터를 주고 받는 기술이다. 원래 대기업의 독점적인 기술이었으나 (갓)구글이 주도해서 오픈소스화 및 표준화를 했다고 한다.
일단 장점은 영상, 오디오, 채팅 모두 리얼타임 서비스가 가능하고 서버를 통해 데이터를 전달하지 않기때문에 속도가 빠르다.
단점은 서버가 없는 P2P기술이기 때문에 많은 사람과 한꺼번에 연결될 경우 방대한 데이터를 보내야하기 때문에 느려진다는 확장성의 제약이 있다.
현재 진행하는 서비스는 1:1 영상통화만 구현하면 되기때문에 webRTC의 단점은 사라지고 장점만 남는다. 그래서 선택하게 되었다. 그리고 영상통화 기능을 구현하려고 찾아봤더니 거의 다 webRTC를 사용해서 구현한것들이 나왔다.
처음드는 생각은 이거였다. 서버가 아예 없는 건가? 그럼 어떻게 연결하지?
WebRTC의 특징은P2P 기술이라는 점인데 클라이언트들을 연결하는 과정이 당연히 필요했다. 각각의 기기가 서버 도움 없이 연결되기 위해 이 연결을 도와주는 서버(Signaling)가 필요하고 P2P 연결이 불가능한 상황을 대비한 릴레이 서버(TURN)가 필요합니다. 즉 서버가 없는것이 아니다.
webRTC서버의 종류는 1. Signaling 서버 2. STUN 서버 3. TURN 서버 4. media 서버 네가지 이다.
1) Signaling 서버
P2P서비스도 서로간의 메타데이터와 호출 시점은 알고 있어야 연결이 성립된다. 전화를 걸어서 서로 통화하는 실질적인 데이터 교환은 P2P 의 영역 이지만 이를 제외한 모든 영역은 시그널링 영역이다. 누가 누구한테 언제 어떤 영상을 요청하고 또 이를 상대방이 수락했는지 안 했는지 등의 메타 정보를 서로 주고 받는 역할을 시그널링 서버가 해 준다.
2) STUN 서버
시그널링을 통해 서로간의 연결 의사를 확인했으면 실질적으로 P2P 연결을 맺기위해 서로간의 네트워크 정보를 알아야 한다. 아이피와 포트들의 정보를 알아야 알기 위해서는 외부에서 해당 클라이언트에 대한 네트워크 상황을 분석해야 하며 이 역할을 STUN 서버가 해 준다.
데이터는 하나만 생성하는게 아니라 가용한 모든 리스트들을 뽑고
(RTCPeerConnection 개체 생성 시, stun 서버 정보를 입력하면 됨)
서로 간의 가용한 목록들이 뽑아지면 (이벤트가 발생) 시그널링 서버를 통해 서로에게 네트워크 정보를 전달함.(icecandidate 라는 이벤트가 발생)
3) TURN 서버
STUN 서버를 통해 icecandidate 가 발생되고, 시그널링서버를 통해 서로 네트워크 정보를 주고 받는다고 무조건 P2P 가 맺어지는 것은 아니다. 각 PEER 간의 네트워크 상황은 제각각이며 예측이 불가능 하고 STUN 서버는 물리적인 네트워크를 분석하여 다양한 정보를 제공할 뿐이고 이중 가용한 정보를 가지고 서로 피어를 맺는 확율 게임인 것이지 무조건 다 맺어주는 마술사가 아니다. (NAT 안에 NAT 안에 안에 안에... 있는 PEER 라고 가정 했을 때 이를 대체 어떻게 뚫음)
이런 상황에서는 서버가 필요한 것이다. 데이터를 중계해 주는 Relay 서버. STUN/TURN 서버로 분리해서 설명하긴 했지만, 사실(일반적으로) 저 둘은 한 서버에 기능이 합쳐져 있다. 기동시에 STUN 기능만 쓸 것인지 STUN 과 TURN 기능을 각 서버로 분리해서 쓸 것이냐는 선택인 것이다.
4) media 서버
미디어 서버는 조금 다른 영역이다. 지금 까지 설명한 서버들은 MESH서버이고 미디어 서버는 다중 연결시 효율적인 데이터 전달을 위한 SFU/MCU 방식인데 이번에 사용할 방식이 아니므로 간단하게 알고 넘어 가기로 했다...
지금까지를 정리해 보면 WebRTC가 동작하기 위해서는 P2P연결이 되어야 하는데 피어끼리 연결이 되기 위해서는 서버가 필요하다. "P2P면 서버가 필요 없는 것 아닌가요?" 라는 의문을 가졌었지만 피어끼리 연결을 하기 위해서는 정보를(메타데이터, 호출시점 등) 교환해야하는데 그 때 서버가 필요한 것이다.
그러면 서버로 피어간에 정보만 전달 시키면 되는 것인가? 이론적으로는 맞지만 인터넷을 하는 사람들 대부분 공유기를 가지고 있기때문에 서버에서 공유하는 피어간의 정보(공인 IP)를 얻기 위해서는 STUN서버, STUN으로 해결하지 못하는 경우 TURN 서버가 필요한 것 이다.
그래서 이러한 과정이 필요하다.
1) 각 브라우저 P2P 커뮤니케이션
2) 서로의 주소 공유
3) 보안 사항 및 방화벽 우회
4) 실시간 데이터 공유
위의 과정이 다 됐다면, 실제로 각 피어끼리의 연결이 완성된다.