[개발] WebRTC & SpringBoot & Vue.js를 활용한 Group Video Call 1 : 이론

Byuk_mm·2022년 4월 23일
16

WebRTC Development

목록 보기
1/2
post-thumbnail

WebRTC?? 쉬워보이던데ㅎㅎ


이번 2022년 1학기 캡스톤 디자인 프로젝트로 팀원들과 온라인 면접에 특화된 온라인 미팅 서비스를 기획했다.
전반적인 컨셉은 Zoom, WebEx와 같은 온라인 미팅 서비스와 비슷하고 그 위에 면접에 도움을 줄 수 있는 기능과 컨셉을 얹은 프로젝트이다.

어찌어찌 하여 나는 프론트 엔드를 담당하게 됐고, 비디오와 오디오 통신하는 Group Video Call 기능 개발에 있어서 풀 스택 개발을 담당하겠다고 팀원들에게 당당하게 선언했다.

당당하게 선언할 수 있었던 이유는 잠깐 찾아보니까 WebRTC라는 API를 이용해서 손 쉽게(그땐 그래보였다 ^ㅡ^) 개발 가능해 보였고, 예시 코드도 많아 보여서 얼른 끝내버려야겠다는 마음이 컸던 것 같다.. 뭐 아무쪼록 잘못된 생각이었음을 느끼는데는 시간이 오래 걸리지는 않았다.


WebRTC를 활용하여 프로젝트 개발 할 때 사용한 기술 스택은 아래와 같다.

Frontend 사이드는 Vue.js를 활용하고,
Backend 사이드는 Spring boot를 활용했다.

둘다 특별한 이유가 있었던 건 아니고,,
Vue.js는 그저 한번 써보고 싶어서였고, Spring은 앞으로 쭉 다뤄야할 프레임워크이기 때문에 한번더 숙련도를 쌓을 겸 사용하기로 했다.

사실 어려움은 여기서 발생한다.. 그룹 화상 통화 기능 개발을 위한 WebRTC를 다루기 위해서, 처음에는 "예시 코드 보면서 빠르게 무지성 복붙해보자~" 라고 생각하며 웹에 있는 코드를 참고하며 끄적끄적 복붙하기를 시도했으나..
웹에 있던 코드들은 대부분 React.js + Node js + Socket.io 기반 코드들이었다.

"예시 코드 무지성 복붙으로 사용"에 실패한 이유는 다음과 같다.

(1) WebRTC 작동 Flow에 대한 정확한 이해도 없을 뿐더러,
(2) Node jsSocket io도 제대로 다뤄본적도 없어서 코드 해석하기도 쉽지 않았다. 그리고,
(3) Spring 기반 소켓 통신과 Node js 기반 소켓 통신의 코드는 분명 차이가 있었고,,,
(4) 심지어 Vue.js는 처음 다뤄보는 상황이었기 때문에
가이드 코드를 내 프로젝트에 맞게 유연하게 변환하는것은 정말로 어려웠다.

깃헙 레파지토리에서 관련 Spring Java 코드들도 많이 찾아보았으나,, 이해하고 적용하기 정말 어려웠고.. 어느정도 시도해보다가 가이드 코드를 그대로 쓰기는 포기했다..

이번 글에서는 내가 WebRTCSpringBootVue.js 환경에서 구현한 과정을 적어보겠다.



WebRTC 개요


코드를 짜기 위해서 가장 절실했던 것은, WebRTC 동작 Flow를 명확히 이해하는 것이었다. 사실 이러한 이해는 단순히 글을 읽는다고 해서 100% 이해되는 부분은 아니라고 생각한다..

나 또한 개념을 몇번이나 반복해서 읽었지만 결국 어느 정도 이해된 시점은 가이드 코드를 다 뜯어보고, 내 코드로 만들어본 시점이었던 것 같다.

하지만 결국 남의 가이드 코드를 이해하기 위해서, 가장 빠르게 그 코드를 해석해서 내 코드로 바꾸기 위해서는 WebRTC에 관한 이해가 선행돼야 한다. 아래로는 WebRTC에 관한 내용을 기재해보았다.

WebRTC(Web Real-Time Communication)별도의 플러그인 설치 없이 실시간으로 미디어(오디오, 비디오, 텍스트, 파일 등)를 최대한 서버를 거치지 않고 Peer간 전송할 수 있는 오픈 소스 웹 기반 기술이다.

위의 그림을 보면 엄청 어려워보인다ㅠㅡㅠ.. 서버만 Signaling Server, TUN Server, STUN Server 3개를 구축해야하는지에 대한 막연함도 생기고,,

WebRTC가 분명 Peer간에 다양한 미디어들이 다이렉트하게 전송될 수 있다고 했는데 결국 서버를 거쳐서 동작하는 건가하는 의문도 들었다. 정확한 동작 Flow를 이해하기 위해서 각각의 서버가 무슨 역할을 하는지 이해해 보자.



서버의 종류


1. Signaling Server

Signaling Server는 WebRTC에서 가장 기본이 되는 서버라고 할 수 있다.
서로 다른 네트워크에 있는 Peer들을 연결시키기위해서는 Session Control Messages, Error Messages, Codec, Bandwith 등 다양한 정보가 필요하다.

결국 WebRTC 기술을 활용해서 Peer끼리 연결하기 위해서는 위의 정보들이 먼저 각각의 Peer들에게 전달돼야 한다는 것이며 이 프로세스를 Signaling이라고 한다.

이러한 정보들을 중계해주는 역할을 하는 서버가 바로 Signaling Server이다.
또한 위의 정보들은 SDP(Session Description Protocol)을 사용한다.

WebRTC와는 별개로 Signaling Server는 직접 구축해야하며,
많은 가이드에서 일반적으로 클라이언트 사이드와 WebSocket을 사용하여 통신한다.

Signaling Server를 중심으로 WebRTC의 동작 과정을 설명해보자면 다음과 같다.

!!! Client와 Server 사이 통신은 WebSocket을 사용한다. !!!

① Client Side의 A Client(Peer)에서 Signaling Server로 연결에 필요한 A Clinet의 데이터를 보낸다.
=> Signaling Offer

② Server Side에서, Signaling Server에 연결된 모든 세션들에게 A Client의 데이터를 전달한다.

③ Client Side의 B Client(Peer)에서 A Client의 데이터를 활용해서 연결에 필요한 일련의 작업을 한 후, B Client의 데이터를 Signaling Server로 보낸다.
=> Signaling Answer

④ Server Side에서, A Client의 세션에게 B Client의 데이터를 전달한다.

각각의 데이터를 활용하여 WebRTC가 A Client와 B Client가 연결한다.


2. STUN Server(Session Traversal Utilities for NAT)

위의 Signaling Server을 이용해서 우리는 Peer간의 통신이 가능하다!
하지만 통신 중간에 방화벽, NAT 환경에 놓여 있는 Peer에 대해서는 직접적인 Signaling이 불가능하다. 이때 이어 설명할 STUN ServerTURN Server가 필요하다.

STUN Server는 클라이언트 자신의 공인 IP(Public Address)를 알려주는 서버이다.
Client에서 STUN Server로 요청을 보내서 자신의 공인 IP를 확인한 후, 해당 IP를 활용하여 Signaling하게 된다.

이러한 STUN Server는 직접 구현할 필요없다.
짧게 생각해봐도 클라이언트 자신의 공인 IP를 알아내는 서버??
내가 직접 만들 필요가 있을까..?

이미 스마트하신분들이 만들어 놓은 오픈 소스, Google 등에서 운영하는 STUN Server를 사용해도 된다!

STUN Server 같은 경우는 단순히 정보 제공을 위한 서버라 트래픽 발생이 현저히 낮기 때문에 웬만하면 무료 STUN Server를 사용해도 문제가 크게는 없다고 한다.


3. TURN(Traversal Using Relays around NAT) Server

앞서 말한 STUN Server를 활용하면 대략 80% 정도는 Signaling을 통한 연결이 가능하다고 한다. 하지만, 그렇지 못한 20%의 경우가 존재하는데, 보호정책이 강한 NAT나 라우터, 보통Symmetric NAT 환경에서 나타난다고 한다.

TURN ServerSymmetric NAT 제한을 우회할 수 있게끔 해주는 기능을 한다.
결국 TURN Server가 Peer간의 통신 채널을 중계해주는 역할을 하며, WebRTC의 가장 큰 특징인 P2P 방식에서 벗어나게 된다.

때문에 Peer간 모든 트래픽을 중계해주기 때문에 상당한 부하를 감당해야하며, 비용 또한 크게 발생할 것이다.

즉, Local IP와 Public IP 둘다로도 연결할 수 없는 경우 TURN Server을 최후의 수단으로 사용하게 된다.

STUN Server처럼 구글에서 무료 제공하는 TURN Server가 있다고 하지만,, 앞서 말한 단점 때문에 현재는 사용을 못한다고 하고,
안정적인 서비스를 위해서는 TURN 서버를 직접 운영하는 것이 필요할 것이다.

구글링을 해보니,
COTURN이라는 오픈 소스를 활용해 TURN 서버를 구축하는 것을 강력 추천했다.

사실 이번 프로젝트에는 TURN Server까지는 활용하지 않고, STUR Server 만 활용할 예정이다 ㅎㅎ..(하다가 문제가 커지면 그때 추가하지않을까)


4. Media Server

WebRTC의 구현 방식에는 크게 3가지로 Mesh, SFU, MCU 방식이 있다.
사실 우리가 지금까지 위에서 말한 방식은 Mesh 방식으로 서버의 자원이 적게들지만 Peer 수가 늘어날 수록 Client 사이드의 과부하가 급격하게 증가하는 방식이다. 때문에 소규모 연결에 적합할 것이다. 이에 대한 설명은 바로 밑 단락에서 하기로 하고,,

Mesh 방식에서는 Media Server가 필요하지 않다.
Media ServerSFU, MCU 방식의 WebRTC에서 필요한 서버로,

각각의 Peer들은 Media Server에게 미디어 스트림들을 쏴주고 Media Server에서 미디어 트래픽을 관리하여 각각의 Peer에게 다시 배포해주는 멀티미디어 미들웨어이다.

즉, WebRTC의 특징은 P2P 통신이 아닌게 되는 것은 TURN Server와 유사하다고 할 수 있고, 클라이언트에 부하가 현저히 줄어드는 대신 서버의 부하가 커지며 구현의 난도가 상당히 높다.

Media Server가 언제, 왜 필요할지에 대해서 제대로 이해하기 위해서 아래 WebRTC 구현 방식에 대해서 살펴보는 것이 좋겠다.



WebRTC 구현 방식의 종류

위에서 언급 했듯, WebRTC의 구현 방식에는 크게 3가지로 Mesh, SFU, MCU 방식이 있다.
구현 방식에 있어서 당연히 장점과 단점이 존재한다. 어떤 방식을 택할지는 정답은 없다.
자신이 현재 하는 프로젝트 스펙에 맞게 정하면 선택하면 된다!
아래로는 간단하게 각각의 방식의 특징과 장단점을 살펴 보겠다. 위 그림을 보면서 글을 읽으면 이해하기 쉽다.

이 블로그에 정말 깔끔하게 정리돼있다!
아래도 위 블로그를 참고하여 작성했다.

1. Mesh 방식

특징

  • 앞서 설명한 Signaling Server, STUN Server, TURN Server를 사용하는 전형적인 P2P WebRTC 구현 방식이다.
  • 1:1 연결 혹은 소규모 연결에 적합하다.

장점

  • Peer간의 Signaling 과정만 서버가 중계하기 때문에 서버의 부하가 적다.
  • 직접적으로 Peer간 연결되기 때문에 실시간 성이 보장된다.

단점

  • 연결된 Client의 수가 늘어날 수록 Client의 과부하가 급격하게 증가한다!
  • 간단하게 생각해봐도 N명이 접속한 화상회의라면, 클라이언트 각각에서 N-1개의 연결을 유지해야 하기 때문이다.

2. MCU(Multi-point Control Unit) 방식

특징

  • 다수의 송출 미디어 데이터를 Media Server에서 혼합(muxing) 또는 가공(transcoding)하여 수신측으로 전달하는 방식.
  • P2P 방식 X, Server와 Client 간의 peer를 연결한다.
  • Media Server의 매우 높은 컴퓨팅 파워가 요구된다.

장점

  • Client의 부하가 크게 줄어든다.
  • N:M 구조에서 사용 가능하다.

단점

  • 실시간 성이 저해된다.
  • 구현 난도가 상당히 어려우며 비디오와 오디오를 혼합 및 가공하는 과정에서 고난도 기술과 서버의 큰 자원이 필요하다.

3. SFU(Selective Forwarding Unit) 방식

특징

  • 각각의 Client 간 미디어 트래픽을 중계하는 Media Server를 두는 방식.
  • P2P 방식 X, Server와 Client 간의 peer를 연결한다.
  • Server에게 자신의 영상 데이터를 보내고, 상대방의 수만큼 데이터를 받는 형식.
  • 1:N 혹은 소규모 N:M 형식의 실시간 스트리밍에 적합하다.

장점

  • Mesh 방식보다 느린 것은 어쩔수 없다. 하지만 비슷한 수준의 실시간성을 유지할 수 있다.
  • Mesh 방식보다는 Client의 부하가 줄어든다.

단점

  • Mesh 방식보다는 서버의 부하가 늘어난다.
  • 대규모 N:M 구조에서는 여전히 Client의 부하가 크다.


마치며,,


사실 포스팅 하나로 끝내려고 했는데,,,
생각보다 짚고 넘어가고 싶은 부분이 많아서 와다다다 이론적인 내용들을 적게 됐다...

WebRTC는 생각보다 쉽지 않은 기술임은 확실하다..
실제로 여러가지로 멘토님께 조언을 구해보니 상용할정도로 개발하려면,
정말로 어려운 기술이다. 신경쓸게 한두가지가 아니다..

다음 포스팅에서는 간단하게 로컬에서 WebRTC
Spring boot & Vue.js & Simple Peer을 활용해서 맛 봐도록 할 것이다.

확실한 것은 위의 내용을 한번이라도 훑고 가면 코드를 이해하기에,,
자신의 코드로 만들기에 훨씬 더 쉬울 것 같다!!

뭐 간단하게 "응 난 집에서만, 집 네트워크에서만 돌릴정도로만 만들어보게~" 라고 한다면 무지성 복붙이 가능하겠지만.. 어느정도 배포까지 해야하고 화상 회의로서 기능을 하게끔 해야 하는 상황이라면 위의 기본적인 정보들을 숙지하는 것은 필수일 것 같다.



참고


https://velog.io/@jsw4215/%EB%A6%AC%EC%95%A1%ED%8A%B8-webRTC-recypumx

https://6987.tistory.com/entry/WebRTC-%EB%AF%B8%EB%94%94%EC%96%B4-%EC%97%B0%EA%B2%B0-%EB%B0%A9%EC%8B%9D-MCU-SFU-P2P

https://kid-dev.tistory.com/4

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://doublem.org/webrtc-story-02/

profile
어디야 벽벽 / 블로그 이전 -> byuk.dev

3개의 댓글

comment-user-thumbnail
2022년 5월 12일

재밌게 잘 봤습니다 :-)
혹시 같은 네트워크의 2개의 client가 STUN 서버를 이용하면 이슈가 없을까요? ( 같은 공인 IP인 경우)
있다면 어떤식으로 해결할까요?

1개의 답글
comment-user-thumbnail
2023년 2월 13일

덕분에 좋은 내용 잘 보고 갑니다.
정말 감사합니다.

답글 달기