졸프를 시작한지 6개월이 넘었지만,, 이제야 정리하는 WebRTC개념 정리
멀티 유저의 영상을 전송하고 전송받은 영상에 Facedetection기술을 접목시키는게 가장 큰 핵심인데, 초창기 이 프로젝트를 기획했을 때와 달리 생각보다 Multi유저간의 실시간 영상을 주고 받는게 더 어려웠고 얼굴감지는 해당 API가 워낙에 잘 되어 있어서 곧바로 얼굴인식 후 이미지를 씌울 수 있었다. 하지만 "WebRTC를 이용해 멀티 유저간의 실시간 영상 전달" 이게 해결이 되어야 FACE API를 적용해 보든가 할텐데 😂😂
현재 이것 때문에 6개월간 도르마무 이지만,,
점점 정리는 되어가는 느낌이다. 제발 얼른 끝내게 해주세요.🙏
WebRTC(Web Real-Time Communications)란, 웹 애플리케이션과 사이트가 중간자 없이 브라우저 간에 오디오나 영상 미디어를 포착하고 마음대로 스트림 할 뿐 아니라 임의의 데이터 교환할 수 있도록 하는 기술이다.
드라이버나 플러그인 설치 없이 웹브라우저간 P2P 연결을 통해 데이터 교환을 가능하게 하는 기술‼
WebRTC는 P2P통신에 최적화가 되어있다.(이것때문에 n개월간 애를 먹었다.)
WebRTC의 주요 API에는 3가지가 있다.(해당 클래스에 의해서 실시간 데이터 교환이 일어난다)
RTCPeerConnection으로 연결하고자 하는 peer의 정보를 주고받아 연결된다.
이 과정을 Signaling이라고 한다.
Caller가 Signaling서버를 통해 자신의 SessionDescription을 보내면 Callee도 마찬가지로 Signaling서버를 통해 자신의 SessionDescription을 보낸다. 그 외에도 ICECandidate를 Signaling서버를 통해 주고 받으며 peer간 연결을 완료하고 Caller와 Callee간에 Media데이터를 주고 받는다.
즉, 두 명의 유저가 스트림을 주고 받는 것이고. 연결 요청을 한 자가 Caller, 연결을 받는 자가 Callee이다. 이 두 사람이 통신을 하기 위한 중간 역할을 해 주는 서버가 SessionDescription이다.
앞서 말했듯이 WebRTC는 P2P에 최적화 되어 있다.
하지만 Peer들 간의 단순 연결 또한 쉽지 않다. 왜? 를 위해서 네트워크를 공부해보자..(네트워크를 배운지 n년이 지나서 개념이 어려웠다)
P2P 연결은 ip:port를 open 하거나 listen 함으로서 동작한다. 따라서 사전에 상호 간 연결 설정을 교환하고 동의해야 하는데, IP주소를 알고 있고 연결할 준비가 되었다고 해서 연결에 성공하는 것이 아니다. 공유기와 같은 라우터 장비 내부에는 NAT이라는 기술이 설정되어 있다.
NAT/방화벽 환경의 클라이언트는 내부망에서 사설 IP를 사용하다가, 외부망과의 인터넷 통신을 위해 NAT장비(라우터 혹은 방화벽)를 통해 공인 IP를 할당받아 인터넷 연결을 하는 구조를 가지고 있다. (NAT개념정리) 이 구조는 외부에 있는 공인 IP로 구성된 호스트에 요청과 응답을 받을 수는 있지만, NAT는 일반적으로 요청하지 않은 패킷은 차단하는 특성을 가지고 있다.
WebRTC는 NAT 통과 기법을 위해 다음의 네트워크 표준을 이용한다.
브라우저가 peer를 통한 연결이 가능하도록 해주는 프레임 워크이다.
- peer간 단순 연결 시 작동하지 않는 이유들
- 연결을 시도하는 방화벽을 통과해야 함
- 단말에 Public IP가 없다면 유일한 주소값을 할당해야 한다.
- 라우터가 peer간의 직접 연결을 허용하지 않을 때 데이터를 릴레이해야 하는 경우
ICE는 위의 작업들을 수행하기 위해 STUN 서버를 이용하여 외부 주소를 획득하고 그것이 실패한다면 TURN 중계 서버를 통해 트래픽을 라우팅한다.
NAT들은 사설 로컬 네트워크에서 디바이스에 IP 주소를 제공하지만 이 주소는 외부에서 사용될 수 없다. 공용 주소가 없이는 WebRTC 피어(Peer)들은 통신할 수 있는 방법이 없다. 이 문제를 해결하기 위해서 WebRTC는 STUN을 사용.
STUN 서버들은 공용 인터넷에서 동작하며 아래와 같은 단순한 한가지 작업을 수행한다.
(NAT 뒤에서 동작한느 어플리케이션으로부터) 전달된 요청의 IP:port 주소를 확인하고 그 주소를 응답으로 되돌려 보낸다.
이 절차는 WebRTC 피어(Peer)가 그 자신에 대해 공용에서 액세스 가능한 주소를 획득할 수 있도록 한 뒤 직접 연결을 설정하기 위한 시그널링 메커니즘을 통해 또다른 피어(Peer)로 전송한다
TURN은 시그널링 데이터가 아니라 피어(Peer)들 사이의 오디오/비디오/데이터 스트리밍 릴레이를 위해 사용
TURN 서버들은 공용 주소들을 가지고 있으므로 설령 피어(Peer)들이 방화벽이나 프록시들 뒤에 존재하더라도 피어(Peer)들이 접속할 수 있다.
봐도봐도 헷갈렸는데 millo님의 정리글을 보고 이해가 잘 되어서 가져왔다.
1. 우선 각각의 peer들은 STUN 서버에 자신의 Public Address와 접근 가능한지 여부를 전달 받는다.
2. Peer1(Caller)이 createOffer를 통해 먼저 자신의 SessionDescription을 생성하고 Signaling Server를 통해 Peer2에게 전달한다.
3. Peer2가 Peer1의 SessionDescription을 전달 받고 이에 대한 답으로 createAnswer을 통해 자신의 SessionDescription을 생성하고 Signaling Server를 통해 Peer1에 전달한다.
4. Peer1과 Peer2 모두 자신의 SessionDescription을 생성한 후부터 자신의 ICECandidate 정보를 생성하기 시작하고 이를 각각 서로에게 전달한다.
5. 서로의 MediaStream을 peer간 통신으로 주고 받는다.
6. 만약 Peer1과 Peer2 둘 중 Symmetric NAT을 가진 Peer가 있는 경우 TURN 서버를 사용해 data relay로 연결을 진행해야 한다.
참고
https://m.blog.naver.com/sehyunfa/221678622407
https://lovejaco.github.io/posts/webrtc-connectivity-and-nat-traversal/
https://millo-l.github.io/WebRTC-%EC%9D%B4%EB%A1%A0-%EC%A0%95%EB%A6%AC%ED%95%98%EA%B8%B0/
https://www.html5rocks.com/ko/tutorials/webrtc/infrastructure/