카테고리 없음

WebRTC(Mesh, MCU, SFU)

신동편 2023. 5. 24. 02:08
728x90

우리 프로젝트의 메인 기능인 화상채팅을 위해서 webRTC라는 기술을 처음 접하게 되었다. 

 

WebRTC는 Web Real-Time Communication이다.

브라우저간의 오디오, 영상 미디어를 스트리밍하며 데이터 교환을 할 수 있도록 하는 기술이다. 실시간으로 웹에서 데이터를 교환할 수 있는 이유는 '시그널링'이라는 NAT 우회 과정을 거치게 된다.

 

STUN 서버에 의해 NAT 트래버셜 작업이 이루어지고 이 STUN 서버에 요청을 보내면 NAT 뒤에 있는 Peer 들이 서로 연결할 수 있는 IP와 포트를 찾아준다.

 

STUN서버가 각 사용자들을 연결해준다. 근데 이 STUN 서버에서 항상 연결을 해주는게 아니기 때문에 이때 대안으로 TURN 서버를 사용한다. 근데 이 TURN 서버는 시간 지연이 필수적으로 발생하니 최후의 수단으로 쓰는 것이 좋다고 한다.

 

이렇게 포트와 ip를 찾고 사용자들을 찾으면 ICE 라는 프레임워크에서 두 단말이 p2p 연결을 하도록 해준다. 연결이 되면 SDP 규약에 맞춰 서로 연결이 되는 것이다.

 

이러한 과정을 '시그널링'이라고 하고 이 시그널링 서버를 직접 구축하거나 외부 솔루션을 사용할 수 있다. 시그널링 서버를 직접 구축하려면 웹소켓, 서버전송이벤트 방법을 적용할 수 있다고 한다.


 

ICE(Interactive Connectivity Establishment)

브라우저가 peer를 통한 연결이 가능하도록 해주는 프레임 워크이다.

peer간 단순 연결 시 작동하지 않는 이유들

- 연결을 시도하는 방화벽을 통과해야 함

- 단말에 Public IP가 없다면 유일한 주소값을 할당해야 한다.

- 라우터가 peer간의 직접 연결을 허용하지 않을 때 데이터를 릴레이해야 하는 경우

- ICE는 위의 작업들을 수행하기 위해 STUN과 TURN 서버 둘 다 혹은 하나의 서버를 사용한다.

 

STUN(Session Traversal Utilities for NAT) 서버

클라이언트 자신의 Public Address(IP:PORT)를 알려준다.

peer간의 직접 연결을 막는 등의 라우터의 제한을 결정하는 프로토콜 (현재 다른 peer가 접근 가능하지 여부 결정)

클라이언트는 인터넷을 통해 클라이언트의 Public Address와 라우터의 NAT 뒤에 있는 클라이언트가 접근 가능한지에 대한 답변을 STUN서버에 요청한다.

 

NAT(Network Address Transilation)

단말에 공개 IP(Public IP) 주소를 할당하기 위해 사용한다.

라우터는 공개 IP 주소를 갖고 있고 모든 단말들은 라우터에 연결되어 있으며 비공개 IP주소(Private IP Address)를 갖는다.

요청은 단말의 비공개 주소로부터 라우터의 공개 주소와 유일한 포트를 기반으로 번역한다. 이 덕분에, 각각의 단말이 유일한 공개 IP 없이 인터넷 상에서 검색 가능하다.

몇몇의 라우터들은 Symmetric NAT이라고 불리우는 제한을 위한 NAT을 채용한다. 즉, peer들이 오직 이전에 연결한 적 있는 연결들만 허용한다. 따라서 STUN서버에 의해 공개 IP주소를 발견한다고 해도 모두가 연결을 할수 있다는 것은 아니다. (위의 설명에서 STUN 서버에 다른 peer가 접근 가능한지 여부를 요청하는 이유)

이를 위해 TURN이 필요하다.

 

TURN(Traversal Using Relays around NAT) 서버

TURN 서버와 연결하고 모든 정보를 그 서버에 전달하는 것으로 Symmetric NAT 제한을 우회하는 것을 의미한다.

이를 위해 TURN 서버와 연결을 한 후 모든 peer들에게 저 서버에 모든 패킷을 보내고 다시 나(TURN서버)에게 전달해달라고 해야 한다.

명백히 오버헤드가 발생하므로 이 방법은 다른 대안이 없을 경우만 사용해야 한다.

 

SDP(Session Description Protocol)

해상도나 형식, 코덱, 암호화등의 멀티미디어 컨텐츠의 연결을 설명하기 위한 표준이다.

두 개의 peer가 다른 한쪽이 데이터가 전송되고 있다는 것을 알게 해준다.

기본적으로 미디어 컨텐츠 자체가 아닌 컨텐츠에 대한 메타데이터 설명이다.

기술적으로 보자면 SDP 는 프로토콜이 아니다. 그러나 데이터 포멧은 디바이스간의 미디어를 공유하기 위한 연결을 설명하기 위해 사용한다.

 

WebRTC는 ICE, STUN, TURN, SDP로 작동된다. 이 서버들과 프로토콜로만 작동이 된다면 매우 간편하겠지만 현실은 그렇지 않다. P2P 연결을 완성시키기 위해서는 개발자가 peer간의 offer와 answer를 통한 session 정보를 중계해주는 서버를 만들어줘야한다. 하지만 P2P 연결로 3인, 4인 그리고 그 이상의 인원의 데이터 송수신을 지원하게 되면 클라이언트 측면에서의 과부하가 심하게 오기 때문에 권장하지 않는다. 이러한 문제의 해결책으로 나온 것이 SFU와 MCU 방식의 미디어 서버를 두는 것이다.


 

 

Mesh

peer간의 offer, answer라는 session정보 signal만을 중계한다. 따라서 처음 WebRTC가 peer간의 정보를 중계할 때만 서버에 부하가 생긴다.

peer간 연결이 완료된 후에는 서버에 별도의 부하가 없다. peer간의 직접 연결로 데이터를 송수신 하기 때문에 실시간 성이 보장된다. 

위 그림과 같이 5명의 사람이 연결을 한다고 하면 Uplink4개, Downlink4개로 한명당 총 8개의 link를 유지하면서 데이터를 송수신하게 된다. 따라서 1:1연결에 적합하다.

 

MCU

다수의 송출 미디어를 중앙 서버에서 혼합 또는 가공하여 수신측으로 전달하는 중앙 서버 방식이다.

위 그림과 같이 5명이 WebRTC에 연결한다면 자신을 제외한 4명의 데이터를 하나의 데이터로 편집해서 받게 된다. 

클라이언트와 서버간의 peer를 연결하게 되는 것이다.

 

모든 연결 형식에서 클라이언트는 연결된 모든 사용자에게 수에 상관없이 서버로 한번만 보내게 되고, 사용자의 수에 상관없이 하나의 데이터만 받게 되는 것이다.

 

따라서 중앙 서버의 높은 컴퓨팅 파워가 요구된다.

 

클라이언트의 부하가 항상 Uplink 1개 Downlink 1개로 매우 적다.

M:N구조에 사용 가능하다. 데이터를 결합하는 과정에서 비용이 많이 들고, 실시간성이 저해된다는 단점이 있다.

 

SFU

종단 간 미디어 트래픽을 중계하는 중앙 서버 방식이다.

MCU와 마찬가지로 서버와 클라이언트간의 peer를 연결한다.

위 그림의 상황으로 따지면 서버에게만 자신의 데이터를 보내고, 서버를 통해서 4명의 데이터를 받게 되는 것이다.

그래서 상대방의 수만큼 peer를 유지해야 한다.

 

데이터가 서버를 거치고 Signaling서버를 사용할 때보다 느리긴 하지만 비슷한 수준의 실시간성을 유지할 수 있다.

Signaling서버를 사용하는 것보다 비용이 증가하고,

대규모 M:N구조에서는 여전히 클라이언트가 많은 부하를 감당해야 한다.


 

  

우리 프로젝트에서는 openVidu 라는 SFU방식의 오픈소스 플랫폼을 사용하여 webRTC 기술을 사용하려고 한다.

다수의 사람과 M:N형식의 화상채팅을 해야하지만 화상채팅방 최대 인원을 8명으로 정해서 그렇게 많은 인원이 아니라고 판단했다. 다수의 사람과 연결해야 하기 때문에 Mesh는 제외했고, 앞서 말했 듯 8명이 많은 인원이 아니라고 판단했다. 또한, 모여서 각자 코딩이라는 주제이니 만큼, 실시간성이 저해되어서는 안된다고 생각했고, 그래서 SFU방식을 선택하기로 했다.

728x90