본문 바로가기
Web/WebRTC

[WebRTC] 무조건 Openvidu를 사용하자 -1 (WebRTC란)

by 정고정 2022. 2. 26.
반응형

글은 두괄식으로 쓰래서 결론부터 썼다.

기술에 있어서 정답은 없기에 무언가를 단언하지 않으려고 노력하지만 이건 진짜 아니다.

제한된 시간 안에 화상을 지원하는 웹서비스 프론트를 react.js로 가져가려면 무조건 openvidu를 쓰는 게 정답이다. 

 

WebRTC에 대한 정보는 정말 많지만 다들 미묘하게 말이 다르고, 그래서 우리가 하는 게 대체 뭔지 알 수가 없었다.

그래서 kurento와 openvidu를 모두 사용해 본 입장에서 이해한 대로 써 보기로 했다. 

개념보다는 실제 개발할 때 공부하거나 고려할 내용 위주로 쓸 것 같다.

 

내 상황은 다음과 같다.

단체 화상 서비스를 제공하는 토이프로젝트 개발 중
Client는 함수형 React.js
Signalling Server는 무조건 자바여야 함
Kurento 쓰다가 마감 4일 남기고 Openvidu로 갈아탐

 

이번 글에서는 WebRTC가 무엇인지, 네트워크를 어떻게 구성할 수 있는지, 실질적으로 우리가 구성해야 할 건 뭔지에 대해 말해보려고 한다. 

 

WebRTC가 뭔가요?

 

WebRTC(Web RealTimm Communication)이란 클라이언트끼리 미디어/텍스트/파일 등을 P2P로 주고 받을 수 있는 기술이다. WebRTC로 구성된 프로그램들은 별도의 소프트웨어 없이 미디어 및 데이터 공유가 가능하다. 기본적으로는 Chromium 오픈소스와 협업하고 있고, 초반에는 웹 브라우저 상에서만 가능했지만 요즘은 모바일도 지원한다. 깃허브를 뒤져 보면 react native에서 WebRTC를 차용한 모바일 어플리케이션을 많이 발견할 수 있다. 

 

그러니까 단순하게 말하면, 화상, 음성과 데이터를 주고 받기 위해 사용하는 기술이다. 

 

WebRTC 연결 구조

WebRTC는 P2P 통신 방식을 사용하지만, 네트워크를 어떻게 구성하느냐에 따라 조금씩 달라진다. 

  • P2P(Peer to Peer)
  • SFU(Selective Forwarding Unit)
  • MCU(MultiPoint Control Unit)

 

P2P

Mesh Topology라고도 하며, 클라이언트끼리 직접적으로 통신하는 방식이다. 각각의 클라이언트(Peer)들이 서버를 거치지 않고 브라우저끼리 직접적으로 통신하므로 속도가 굉장히 빠르다.

 

클라이언트 이외 별도의 서버를 구축할 필요가 없으므로 구현하기가 가장 간편하다. 이 경우는 kurento냐 openvidu냐를 고민할 필요도 없다.  

 

하지만 보다시피 각각의 피어가 다른 모든 피어와 연결되어 있어야 하므로 클라이언트 부하가 굉장히 심하다. 1:1통신일 경우에는 별 문제가 없지만 만약 회장님 연설을 듣기 위해 전직원이 모인 웹엑스가 Mesh WebRTC로 되어 있다면...? 난리남

 

장점

  • 전체적으로 정말 단순하다. 
  • 각각의 participant들이 p2p로 연결되기 때문에 별도의 서버가 필요하지 않다. 

단점

  • 대략 4-6명의 participant까지만 연결할 수 있다. 
  • 각각의 participant는 N-1개의 uplink와 N-1개의 downlink를 가져야만 한다. 

SFU

 

Routing Topology를 사용한다. 중앙 서버가 다른 피어의 시그널을 깡그리 모아다가 보내 주므로 각각의 피어는 중앙서버로만 본인의 시그널을 송신하면 된다. p2p mesh 방식보다 클라이언트 부하가 적지만 시그널이 서버를 한 번 거쳐 가는 방식이므로 속도에서 미묘한 차이를 보인다.

 

이 중앙서버를 SFU라고 부른다고도 하는데, 이 구조 자체를 SFU 방식이라고 더 많이 부르는 것 같다.

 

일반적으로 1:N(N:N) 단체 통신을 구축하기 위해 많이 차용하는 방식이며, 여기서부터 이 서버를 kurento로 가져갈 거냐 openvidu로 가져갈 거냐 하는 고민이 시작된다. 따지고 들어가자면 openvidu도 쿠렌토긴 하다. 

 

장점

  • MCU에 비해 처리능력이 낮아도 된다. 
  • 각 participant는 하나의 uplink와 N-1개의 downlink를 가진다. 

단점

  • 서버단 구축이 복잡하다. 

MCU

MCU에서는 서버가 모든 걸 처리한다. 서버는 이제 시그널링을 전달해 줄 뿐만이 아니라 다른 피어들이 송신하는 미디어 자체를 믹싱해서 하나로 보내준다. 클라이언트의 부담을 모두 서버가 지는 방식이고, 서버에서 믹싱까지 담당하므로 SFU에 비해서는 당연히 속도가 느리다.

 

서버는 높은 프로세싱 처리능력을 필수적으로 요구한다. 배포 당시 사용했던 ec2 컨테이너는 램이 16기가짜리라 무리가 없었다. 

 

MCU 구조에서 미디어를 인코딩해 주는 이 중앙서버가 바로 미디어서버다. WebRTC를 차용한 단체 화상 어플리케이션을 개발한다면 최소한 KMS(Kurento Media Server)를 도커로 하나 돌려야 한다. 

 

 

장점

  • 클라이언트는 정말 단순한 WebRTC만 구현하면 된다. 
  • 각 피어는 단 하나의 uplink와 downlink만 수행한다. 

단점

  • MCU 서버는 각 participant의 미디어를 decoding/encoding하기 때문에 처리능력이 정말 좋아야 한다. 

 

👉Kurento와 Openvidu는 MCU일까 SFU일까?

 

우리가 실제로 돌려야 할 서버

사실, 부가적인 이익을 추구할 게 아닌 한 토이프로젝트 수준에서는 세 가지 방식 중에 뭘 선택할지 고려할 필요도 없다. 

WebRTC를 이용해 다대다 화상서비스를 구축하기 위해서는 순수한 P2P 방식으로는 어렵다.

단순하긴 하지만 클라이언트 부하가 너무 크고, 효율적인 방식도 아니다. 

결정적으로 P2P Mesh 방식으로 1:N 통신을 구현한 데모도 마땅찮다.

 

여기서부터는 Kurento를 쌩으로 쓸 거냐 Openvidu를 쓸 거냐두고 슬슬 간을 봐야 한다.

Kurento는 아래 언급한 서버들을 모두 우리가 설치하고, 세팅해서 연결해줘야 한다. 

Openvidu의 경우는 docker compose를 이용해서 명령어 하나만으로도 세팅 된 여러개의 도커 컨테이너를 한 번에 돌릴 수 있다. 

 

WebRTC 구현을 위해 돌려야 하는 서버부터 확인해보자.

배포하려면 coturn도 필요함

 

Signalling Server

시그널링 서버는 각 피어가 실질적으로 요청을 날리는 서버다. 클라이언트는 다른 서버에게 요청을 날릴 필요가 없다. 오직 시그널링 서버에만 쏘면 된다. 

이 시그널링 서버를 Kurento로 쓸 거냐 Openvidu로 쓸 거냐 결정해야 한다.

모두 maven으로 개발된 Signalling server를 제공하고 있고, 클라이언트만 있는 데모와 시그널링이 node js로 된 데모 등등 제공하니 골라 쓰면 될 것 같다. 

무얼 쓸 거냐에 따라 클라이언트단에 설치해야 하는 npm package도 달라진다. 

Media Server

앞서 말한, 피어들의 미디어를 믹싱해주는 친구다. 

kms(Kurento Media Server)를 사용하는데, 보통은 도커로 돌린다. Kurento의 경우 kms 도커를 돌려놓은 다음에 그 안에 있는 설정파일에서 coturn 경로를 잡아줘야 한다. 

Turn/STUN Server

배포하기 위해서는 필수적인 친구다. 

WebRTC는 기본적으로 P2P 기반이기 때문에 각 피어가 공인 IP를 가지고 있거나, 같은 네트워크 망 안에 있어야 한다. 하지만 그러면 로컬이나 다름 없기에 실배포를 위해서는 중간에 중계서버 하나가 있어야 한다.  

배포 컨테이너에다가 클라이언트 돌리고, 시그널링이랑 미디어서버까지 돌려 놓더라도 turn서버가 없거나 뭔가 설정이 잘못된다면 다른 사람의 영상이 보이질 않는다. 

 

보통 이 중계 서버로 coturn이라는 오픈소스를 사용한다. 이 친구를 설치해주면 NAT도 뚫고 다른 네트워크 망에 접근도 하고 할 수 있다. 

리눅스에서만 구동이 가능하고, 공인 IP를 가진 서버에만 설치할 수 있지만 보통 배포를 위해 사용하는 ec2 컨테이너는 해당 조건을 모두 만족한다.  

Client

당연하게 클라이언트도 하나 돌아야 한다. 백엔드API서버랑 같이 돌든 REST로 따로 돌든.

Kurento와 Openvidu 모두 클라이언트 개발을 위한 npm package를 제공한다. 물론 데모도 풍부함. 

kurento는 kurento-utils를, openvidu는 openvidu-browser를 설치하면 된다. 

피어가 되는 클라이언트는 설정에 따라 본인의 미디어나 짧은 텍스트, 파일을 시그널링 서버로 날릴 수 있다. 

 

 

그러면 한 가지 궁금증이 생긴다.

중간에 시그널링 서버를 둔다면, 과연 사용자의 미디어도 시그널링 서버를 거칠까?

 

어떤 데이터가 어떤 서버를 거칠까?

https://doc-kurento.readthedocs.io/en/latest/user/intro.html

 

우리는 중간에 시그널링 서버로 java app server를 하나 뒀다. 

클라이언트가 날린 시그널을 받은 앱 서버는 쿠렌토 프로토콜을 통해 KMS와 통신하고, 미디어는 클라이언트에서 KMS로 직접 흘러간다.

 

kurento는 websocket으로 시그널링 서버와 통신을 진행하고, openvidu는 REST 방식으로 시그널링 서버와 통신한다. 

둘 다 TCP 프로토콜이다. 

WebRTC에서 미디어는 기본적으로 UDP 통신을 통해 진행된다. 

최초 연결 시 peer끼리 서로의 iceCandidate를 주고 받아서 경로를 확인한 다음부터는 peer끼리 직접적으로 연결되어서 UDP 통신으로 미디어를 주고 받는다.

KMS docker를 설치할 때 UDP 포트를 열어주는 이유다.

 

👉 docker로 KMS 실행하기([Kurento] 배포 가이드/네트워크 구성)

 

덧붙이자면 WebRTC에서 UDP를 이용해 데이터를 주고 받고, 해석하기 위해 사용하는 프로토콜이 바로 RTP와 RTCP다. 

 

 

다음 글에서는 Openvidu와 Kurento에 대해 본격적으로 비교할 예정이다. 

결론은 정해져 있다. 

Openvidu다. 

 

👉다음 글 가기

 

[WebRTC] 무조건 Openvidu를 사용하자 -2 (OpenVidu vs Kurento)

진짜 쓰고 싶은 말은 이거였다. 분명 둘 다 써 보신 분이 많을 텐데 관련 글이 정말 없었다. 기왕 굴러 본 김에 OpenVidu와 Kurento를 비교해보려고 한다. Openvidu와 Kurento가 각각 무엇인지, 실질적으로

butfound.tistory.com

 

 

반응형

댓글