Web RTC를 도입하려고 한 이유
스터디를 진행하면서 꼭 필요한건 바로 화상회의가 아닌가 싶다.
나는 스터디 웹을 개발하는 도중 위와 같은 요구사항을 만족하기 위해 화상회의 개발을 위해 공부를 진행했고 이를 위해 WebRTC를 도입해야겠다고 생각했다.
이를 위해 WebRTC에 대해 알아야했고 공부했던 내용을 정리하고 공유하고자 한다.
Web RTC란?
Web RTC란, Web Real-Time Communication의 약자이며 JS API로 위와 같은 기능들을 제공해주는 오픈소스일뿐이고 우리가 직접 구현해야 한다.
먼저, Web RTC에 대해 간단히 살펴보자.
Web RTC를 간단히 번역해보자면 웹 실시간 통신이라는 것을 쉽게 알 수 있는데 이 말에서 의미하는 바와 같이 웹, 앱에서 비디오, 마이크 등을 이용해서 실시간 통신을 제공한다는 것이다.
Web RTC에서는 우리가 실시간 통신을 하면서 나오는 데이터(비디오에서 나오는 영상 스트림, 마이크에서 나오는 음성 스트림)들을 P2P방식으로 Peer 간의 전송이 되도록 지원하고 있다.
"왜 Web RTC인가?" 라고 누군가는 질문을 던질 수 있을 것이다.
놀라운 점은 줌과 다른 화상회의 프로그램과 같이 단순 설치없이 웹이나 앱상에서 바로 이용이 가능하다는 점이다.
또한, 화상 회의를 진행하면서 지연(Latency)가 매우 짧다는 장점이 존재한다.(흔히 유튜브에서 사용하는 RTMP보다 낮은 Latency를 가지고 있다.)
하지만 필요시 STUN 서버와 TURN 서버를 구축해야한다는 등의 번거로운 점이 존재하지만 위의 장점들은 충분히 이러한 부분들을 극복할 만한 장점이라고 생각한다.
간단하게 Web RTC에 대해 알아보았으니 이제 더 깊숙하게 들어가보자.
Web RTC에서는 다양한 개념들을 다룬다.
이들을 간단히 언급하자면 시그널링(Signaling), ICE(Interactive Connectivity Establishment), STUN(Session Traversal Utilities for NAT), TURN(Traversal Using Relay NAT) 등이 존재한다.
각각에 대해 천천히 시나리오를 그려가며 알아가보자.
시그널링
위에서 언급했듯이 우리는 상대방과 P2P연결을 통해 데이터를 상호교환한다.
하지만 연결을 하고 교환하기 전에 고려해야할 부분은 몇몇 존재한다.
먼저, 상대방과 연결을 하기 위해서는 상대방의 네트워크 정보가 필요할 것이며 상대방이 보내는 미디어 데이터 정보(해상도, 형식, 코덱 등)가 무엇인지에 대해 알고 전송과 수신 여부에 대해서 알아야할 필요가 있을 것이다.
정리하자면 다음과 같다.
세션 제어 정보 - 통신의 초기화, 종료, 에러
네트워크 정보 - IP, PORT
미디어 정보 - SDP 형식으로 코덱, 해상도, 송수신 여부를 응답 모델(Offer <-> Answer)을 통해 협상
(SDP(Session Description Protocol)이란, 위에서 언급한 두 개의 Peer 간에 다양한 멀티미디어 컨텐츠의 초기 인수를 설명하기 위한 프로토콜이다.)
그래서 우리는 시그널링(Signaling)을 진행한다.
우리는 시그널링 서버를 구축하고 시그널링을 통해 Peer간 위에서 언급한 정보들을 교환한다.
Web RTC에서는 이러한 시그널링에 대해서 어떠한 제한을 두고 있지 않으며 우리가 어떠한 방식으로도 시그널링을 진행할 수 있다. (이 부분이 오히려 우리를 힘들게 한 것일지도 모른다...)
시그널링의 모습을 실제로 확인해보면 아래 그림과 같다.
위에서 실제로 시그널링 서버에서 정보가 교환되고 이를 토대로 P2P 연결을 통해 실시간 통신을 진행한다.
NAT
우리는 글로벌 인터넷 세계에서 살아가고 있기에 수많은 IP들이 각각의 컴퓨터들에 할당되어 누구와도 소통할 수 있다.
하지만 우리가 사용하는 IPv4 체계는 전 세계의 사람들을 충당하기에는 너무 부족하다. (2^32 => 4,294,967,296)
IPv6가 나온다면 지금보다 나아질 것이지만 그에 대한 대안으로 단순 사설 IP를 사용하기보다는 공인 IP를 사용하기로 하였다. (물론 보안의 목적으로서도 충분한 가치가 있지만 네트워크에 대해 자세하게 다루는 부분이 아니므로 NAT에 대해 찾아보시면 좋습니다.)
이것을 해결해주는 것이 바로 NAT(Network Address Traversal)이다.
이에 대한 예는 우리 주변에서 충분히 찾아볼 수 있다.
집에서 각각의 컴퓨터들을 사용하고 핸드폰을 위한 와이파이도 사용하고 다른 스마트 제품들을 위한 인터넷도 공유기를 통해 받는다.
즉, 하나의 공인 IP를 여러 개의 사설 IP로 쪼개 안에서 사용하고 있으면서 외부와 통신할 때는 앞에서 언급한 공인 IP로 통신을 진행하게 된다는 것이다.
하지만 이렇게 되면 외부 IP를 사용해 외부로 나갔다가 다시 결과값이 반환되어 들어올 때 해당 공인 IP를 목적지로 해서 들어올 텐데 어떤 사설 IP에서 요청했는지 어떻게 알지? 라는 의문을 품을 수도 있는데 NAT는 테이블을 통해 내부 네트워크에 존재하는 사설 IP와 포트 번호를 외부 네트워크와 통신할 때 사용하는 공인 IP와 포트와 매핑하여 저장해놓음으로써 이를 가능하게 해준다.
STUN, 홀 펀칭
그렇다면 A라는 사람과 B라는 사람이 WebRTC를 이용할 때 A가 B의 공인 IP로 보내면 NAT에서 알아서 B의 사설 IP로 보내주겠지?라고 생각하면 오산이다.
우리에게 아직 문제점이 존재한다.
NAT의 경우, B가 요청을 보내면서 NAT를 거치며 해당 사설 IP 정보와 공인 IP 정보가 매핑되어 테이블에 저장되게 되면 위의 경우는 성립한다.
하지만, 어느 것도 없던 경우 A와 B NAT 테이블에는 어떠한 것도 존재하지 않으므로 각각에 도착할 수 없을 것이다.
이를 위해 존재하는 것이 바로 홀 펀칭(Hole Punching)이다.
여기서는 추가적인 서버 S가 존재한다고 하자.
A와 B는 각각 서버 S에 접속하게 되면 NAT를 통해 공인 IP로 변환(Traversal)되어 가므로 S에서는 해당 공인 IP를 알 수 있으며 A와 B가 사설 IP도 알려준다면 사설 IP 정보까지 캐치할 수 있게 된다.
S가 이제 A, B에게 각각의 정보에 대해서 알려준다. 여기까지 된다면, 서버 S의 존재 가치는 여기서 끝이다.
A와 B가 받은 정보를 토대로 각자 진행하면 될 것이다.
이러한 과정을 그림으로 표현하면 아래와 같다.
이것이 바로 우리가 위에서 언급한 STUN(Session Traversal Utilities for NAT)의 존재이유이다.
사설 IP와 방화벽의 세계에서의 문제점을 해결해준다.
TURN
하지만 문제점은 추가적으로 존재한다.
그 부분은 NAT의 종류에 따라 발생하게 되는데 이를 알기 위해 NAT 종류에 대해 간단히 살펴보자
- Full cone NAT
- A 서버로 요청을 보내기 위해 한번 [사설 IP/PORT : 공인 IP/PORT] 쌍이 NAT 테이블에 저장되면 항상 그 공인 IP/PORT로의 요청은 해당 사설 IP/PORT로 간다.
- B 서버와 통신을 한적이 없는 데도 불구하고 NAT 매핑 정보만 안다면 해당 사설 IP/PORT로 정보 전송이 가능하다.
- Address Restrict Cone NAT
- Full Cone NAT에서와 달리 기존에 통신하던 서버가 아니라면 불가하다. (위에서 A 서버만 가능, B 불가)
- Port Restricted Cone NAT
- Address Restrict Cone NAT에서 포트도 본다.
- Symmetric NAT
- 위 세 개와 달리 다른 서버와 통신을 하게 된다면 매핑 정보가 아예 바뀌어 버린다.
여기서 문제가 되는 부분은 Symmetric NAT이다.
우리가 기껏 STUN Server를 통해서 사설 IP/PORT와 공인 IP/PORT를 알아왔더니 A, B 각자와 통신을 할때에는 매핑 정보가 아예 바뀌어버려 사용할수도 없게 된다.
이러한 부분을 해결하기 위해 등장한 것이 바로 TURN(Traversal Using Relay NAT)이다.
이 부분에 대한 설명은 간단하다.
그냥 단순히 TURN Server과 A, B가 각각 연결을 맺고 이 서버에서 모든 교환 과정을 중계해준다.
즉, 아래와 같은 그림을 살펴볼 수 있다.
정리
이와 같이 우리는 A라는 사용자와 B라는 사용자가 PeerConnection을 맺기 위해 정보를 교환하는 과정에 대해서 알아보았다.
위에서 설명한 과정들 속에서 상대방의 네트워크 정보를 알게 되는데 각각을 사용해서 얻을 수 있는 정보는 다음과 같다.
- 자신의 사설 IP/PORT
- 자신의 공인 IP/PORT (By STUN, TURN)
- TURN 서버의 IP/PORT (By TURN)
이렇게 상대방과 연결하기 위한 최적의 경로를 알기 위한 과정을 제공하는 프레임워크를 바로 ICE(Interactive Connectivity Establishment)라고 한다.
아래 그림이 Web RTC의 전체적인 구조를 잘 표현하고 있다고 생각한다.
그리고 아래 그림이 전체적인 과정 순서를 잘 나타내고 있다고 생각한다.
이제 대강 Web RTC의 기본적인 이론에 대해서는 설명했고 정리하자면 다음과 같다.
- 상대방의 네트워크 정보와 미디어 정보를 알기 위해 시그널링 과정을 거친다.
- 네트워크 정보에 대해서 문제점이 발생하는 경우가 빈번히 있기에 이러한 부분을 해결하기 위해 ICE 프레임워크로 최적의 경로를 찾게 된다.
- 이에 대한 방법으로는 STUN, TURN 서버를 이용하는 방법이 존재한다.
실제 Web RTC의 아키텍처는 다음과 같이 구성되어 있고
웹 개발자인 우리는 보라색 부분에 보이는 API를 활용해서 원하는 실시간 통신을 구현하면 될 것이다. (브라우저 개발자라면 초록색 부분과 파란색 부분 또한 고려해야 할 것이다.)
간단하게 Web RTC에 대해서 적어보았다.
위에서 Web RTC는 Peer 간에 Peer-To-Peer로 이루어진다고 설명을 했는데 이 방식은 사람의 수가 늘어날 수록 부담이 매우 심해지게 된다.
이에 대한 개선 방향으로 다양한 통신 방법이 나왔는데 다음 포스트에서는 이 부분에 대해서 다루려고 한다.
'개발일지' 카테고리의 다른 글
[Junit5] Static Method Mocking (0) | 2022.02.08 |
---|---|
[WebRTC] WebRTC의 다양한 방식들 (Mesh, SFU, MCU) (0) | 2022.02.07 |
JPA에서의 일급 컬렉션 적용 (0) | 2022.01.02 |
값 타입 컬렉션 ➡ 엔티티 (0) | 2022.01.02 |
@ElementCollections 사용기 (0) | 2022.01.01 |