brunch

매거진 WebRTC

You can make anything
by writing

C.S.Lewis

by 에디의 기술블로그 Sep 19. 2021

2. 화상 회의 서비스를 위한, WebRTC 소개

Overview


작년 코로나 이후로, 필자는 계속 재택근무를 하고 있는데, 거의 매일 화상 회의를 하고 있다. 코로나가 당장 없어지지 않는다면 집에서 화상 회의로 팀원들과 온라인으로 대화하는 삶은 당분간 지속될 것이다. 화상 회의 시 가장 많이 사용하는 서비스는 구글 Meet, Zoom인데, 이런 화상 회의 서비스들은 영상 및 음성 데이터를 통신할 때 어떤 기술을 사용할까? 


이 글에서는, 화상 회의 서비스의 핵심 기술인 WebRTC에 대해서 소개할 예정이며, 화상회의 서비스를 직접 구축하면서 간략하게 기술 검토를 할 예정이다.


목차

[이전글] 1. 코로나 시대에서의 WebRTC

[이번글] 2. 화상 회의 서비스를 위한, WebRTC 소개

[다음글, 미정] 3. WebRTC 심화 및 시그널링 서버 구축(스프링부트 기반의 WebSocket 서버)

[미정] 4.WebRTC 화상 회의 서비스 완성 (Vue.js & Nginx 웹서버)


필자의 지난 글을 읽지 않았다면 읽어보고 오길 바란다. 

https://brunch.co.kr/@springboot/639


생각의 흐름대로 작성한 글이라서 매우 지루하고 재미없다. 게다가, WebRTC에 대한 상세 스펙 또한 상세하게 다루지 않는다. 관심 있는 개발자는 레퍼런스를 직접 찾아보길 바라며...가벼운 마음으로 편하게 읽어주길 바란다. WebRTC를 잘 아는 개발자 또는 경력자는 필자의 글을 굳이 안 읽어도 될 것이다. 주니어 개발자 또는 취준생만 읽어보길 바라며, 필자의 글에서 다루지 못한 내용은 각자 공부하길 바란다.




저는, 회사 업무 시간에 절대로 글을 쓰지 않으며, 모든 글은 주말 또는 휴가 중에 작성합니다. 또한, 최근에 회사 업무로 WebRTC 기술을 잠시 검토했지만, 회사 업무 관련 내용은 회사의 허락 없이 절대 작성하지 않습니다. 회사 업무와 별개로, 일반적이고 개인적인 생각으로 작성한 글입니다.


잘못된 내용이 있다면 제보 부탁드립니다! 





2장을 시작하기 전에


필자가 재미난 기사를 소개하겠다. 최근 "게더타운" 이라는 메타버스 서비스가 인기이다. 모 회사에서 신입사원 연수를 온라인으로 진행하였는데, "게더타운" 서비스에서 아바타로 첫 출근을 했다고 한다. 


https://www.youtube.com/watch?v=e0EKrESr0UE


"게더타운"은 가상의 공간에서 만나서 대화 및 업무 또는 교육 등 다양한 목적을 지원해주는 온라인 메타버스 플랫폼이다. 공간을 자유롭게 꾸밀 수 있고, 통화 또는 영상 회의도 가능하다. 


근데 어쩌라고? 


갑자기 게더타운 서비스를 소개를 하는 이유는, 바로 WebRTC 기반으로 구축이 되어있기 때문이다. 게더타운 외에 수많은 서비스가 WebRTC 를 사용하였다. 필자의 지난 글을 읽어보길 바란다.

https://brunch.co.kr/@springboot/639



2.화상 회의 서비스를 위한, WebRTC 개요


2장에서는, 클라이언트가 서버와 통신하는 방법 및 WebRTC에 대해서 이것저것 간략하게 소개한다. 


2.1 클라이언트(브라우저)가 서버와 통신하는 방법

클라이언트-서버 아키텍처이다. 매우 일반적이고, 우리에게 익숙한 모델이다. 

우리가 사용하는 기술의 핵심은 바로 HTTP 이다. 웹의 동작 방식에 대해서는 이 글에서는 생략한다. 


[주니어 개발자는, TCP/IP, DNS, HTTP 등 웹을 지탱하는 기술에 대해서 공부하길 바랍니다.]


https://developer.mozilla.org/ko/docs/Learn/Getting_started_with_the_web/How_the_Web_works


필자가 아주 오래전에 포털 메인 화면의 데이터를 실시간으로 변경하는 기능을 개발한 적이 있다. 예를 들어서, 실시간 검색어 같은 기능이다. 

실시간 검색어는 주기적으로 업데이트가 되어야 한다. 참고로 현재 네이버, 다음 등 주요 포털에서 실시간 검색어 영역이 사라진 상황이다. 어쨋든, 당시, 데이터를 어떤 방식으로 실시간으로 업데이트 해줬을까? 사실 조금 무식한 방법으로 서비스를 구축했었다. 클라이언트(웹브라우저)에서 서버에 Ajax 통신을 주기적으로 요청한 후, 응답 받은 데이터를 화면에 렌더링하는 방식으로 개발했었다. 즉, 30초 또는 1분에 한번씩 클라이언트에서 서버에 실시간 검색어 최신 데이터를 요청하며, 최신 데이터를 가져와서 화면에 업데이트를 해주는 방식이다. 1분 사이에 실시간 검색어가 똑같을 수 있다. 하지만, 클라이언트는 실시간 검색어 데이터가 똑같은지, 변경되었는지 알수 없다. 그래서, 조금 무식하지만 주기적으로 계속 호출해서 변경된 데이터가 있는지 확인할 수 밖에 없다.

폴링


위와 같은 방식을, 조금 고급진 용어로 "폴링" 이라고 표현한다. (더 개선된 방법으로 롱폴링으로 개발할 수 도 있다.)


암튼, 당시에는 위 방법이 최선이었다. 브라우저마다 지원하는 기술이 조금씩 다르지만, 당시에는 인터넷 익스플러로가 사용 비율이 가장 높았던 시절이었다. 아휴... 정말 IE 모든 버전에 호환되도록 화면을 개발하는 일은 정말 짜증나는 일이었다. 인터넷 익스플로어를 포함해서 크롬, 파이어폭스 등 모든 웹브라우저에서 동작하도록 하기 위해서는 위 방식이 최선이었다.


하지만, 주기적으로 호출하는 위와 같은 폴링 방식보다는, 서버에서 클라이언트로 변경이 필요한 데이터를 푸쉬(전송)해주면 더 효율적일 것이다. 


이때 우리가 생각해볼 수 있는 기술이 바로, "Server-Sent Events"(이하 SSE)이다. SSE 역시 HTTP 프로토콜에 의해서 동작한다. 대충 그림을 그려보면 아래와 같다. 

Server-Sent Event


SSE는 실시간검색어 뿐만 아니라, 주식 정보, 날씨 정보 등의 데이터를 업데이트할때 사용하면 좋을 것이다. 서버에서 클라이언트에 단방향으로 제공하는 데이터이다. 단점으로는, 모든 브라우저에서 지원하지 않는다. 하지만, polyfill 등을 사용해서 어떻게든 해결할 수 있을 것이다. (최근에는 필자가 직접 해보지 않아서 자세히는 모르겠다.) 실시간 검색어, 주식, 날씨 정보와 같은 데이터는 양방향 통신이 필요 없다. 서버에서 업데이트가 필요한 시점에 클라이언트에 단방향으로 데이터를 전송해주면 된다. 



반면에, 웹사이트에 채팅 기능을 만든다고 가정해보자. 채팅은, 상대방의 메시지를 실시간으로 전달 받아야하며, 내가 작성한 메시지를 상대방에게 실시간으로 보내야한다. 즉, 채팅 기능은 채팅을 하는 모든 사용자가 실시간으로 양방향 통신을 해야 한다. 이 경우, 폴링, SSE 등의 기술이 적합하지는 않다. 물론, 억지로 구현은 가능하지만, 복잡하고 비효율적인 설계가 될 것이다. 


그럼, 양방향 통신을 위한 대안은 어떤 기술이 있을까? 이때, 생각해볼 수 있는 기술이 바로 웹소켓(이하 WebSocket)이다. 채팅 서비스는 내가 작성한 메시지가 상대방에서 실시간으로 전송이 되며, 상대방이 작성한 메시지를 실시간으로 내 화면에 보여줘야 한다. 채팅을 하는 모든 사용자는, 중앙 서버를 통해서 실시간으로 양방향 통신을 해야 한다. 필자의 허접한 그림을 보고 이해해보자.


사람1 채팅 화면: 안녕~ 

사람2 채팅 화면: (사람1에게 받은 메시지) 안녕~

사람2 채팅 화면: 응! 반가워~

사람1 채팅 화면: (사람2에게 받은 메시지) 그래 반갑다.


웹소켓은 TCP 연결을 통해서, 양방향 통신 채널을 제공하는 기술이며, 간단한 채팅 서비스는 WebSocket 으로 어렵지 않게 만들 수 있다. 웹소켓에 대한 상세한 설명은 생략한다. 


[주니어 개발자는, 웹소켓에 대해서 따로 공부하길 바랍니다.]


화상 회의 서비스는WebSocket 으로 구현할 수 있을 것이다. 두명 이상의 접속자가 화상 회의 서비스를 한다고 가정하면 아래와 같을 것이다. 

화상 회의는, 단순한 텍스트 메시지를 주고 받는 수준을 넘어서, 카메라에 의해서 실시간으로 찍히고 있는 내 영상 정보를 상대방에서 전송해야 한다. 필자가 WebSocket 으로 화상 회의를 개발해본적이 없어서, 위와 같은 방식이 가능한지는 확신이 없지만... 가능할 것 같다. 혹시, 경험자는 알려주길 바란다. (아니다, 안알려줘도 된다. 어차피 이 글의 핵심 주제는 WebRTC 이다.)


위와 같이 WebSocket(웹소켓)을 사용한 화상 회의 시스템은, 클라이언트와 서버 사이에 네트워크가 느린 상황이라면, 영상 및 음성 정보가 서버를 통해서 전달되는 순간에 약간의 딜레이가 발생할 수 있다. 즉, 내 영상과 음성이 상대방에게 늦게 전달 될 수 있게 된다. 카메라에 의한 내 화면을 상대방에게 지연없이 실시간으로 보여줄 수는 없을까? 


혹시, 서버를 통하지 않고, 데이터(영상, 음성) 정보를 직접 주고 받으면 훨씬 빠르지 않을까??

결론 먼저 말하면, WebRTC 를 사용해서 위와 같은 P2P 기반의 화상 회의 서비스를 구축할 수 있다. 이번 글에서는, WebRTC 에 대해서 가벼운 마음으로 알아보겠다. 하지만 이 글에서 WebRTC 에 대해서 100 분에 1 도 설명하지 못할 것이다. 필자의 글에서 다루지 않는 내용은, 각자 따로 공부해야 이해가 될 것이다. 


2.2 WebRTC vs WebSocket


WebRTC 에 대해서 상세하게 알아보기 전에, WebSocket 과 차이에 대해서 한번 더 정리하고 넘어가자.


WebRTC 는 비디오, 오디오 등의 데이터를 클라이언트 간에 직접 스트리밍 할 수 있어서, 네트워크 성능 비용이 크게 절감된다. 반면에, WebSocket 은 클라이언트와 서버 사이의 양방향 통신을 위해 설계 되었고, 비디오 등의 데이터를 스트리밍 할수는 있지만, WebRTC 만큼 효율적이지는 않다.  또한, WebSocket 은 TCP 프로토콜을 사용하지만, WebRTC 는 UDP 를 사용한다.  어쨋든, 화상회의 서비스에는 WebRTC 를 사용하는게 좋겠다는 판단이지만, WebRTC 는 모든 브라우저에서 지원하는 것은 아니라는 사실도 알아두어야 한다. 기술에 정답은 없다.


자세한 설명은 생략한다. 따로 찾아보길 바라며, 나중에 3장에서 글을 써보겠다. 


[TO.주니어 개발자] WebRTC vs WebSocket 장단점 정리



2.3 WebRTC 간략하게 소개

2.3.1 WebRTC 란?

WebRTC (Web Real-Time Communication)는 웹 브라우저 간에 플러그인의 도움 없이 서로 통신할 수 있도록 설계된 API이다. 음성 통화, 영상 통화, P2P 파일 공유 등으로 활용될 수 있다. WebRTC 는 구글에서 적극적으로 지원하고 있는데, 구글 Meet, Zoom, 페이스북 등의 서비스에서 사용된다. 


중간 서버를 거치지 않고, 상대방에게 직접 비디오, 오디오 정보를 통신할 수 있다면, 더 빠르게 전송할 수 있지 않을까? 실시간으로, 지연 없이, 데이터를 바로 전송하는 것이다!!

만약 3명 이상에서 화상회의를 한다면 아래와 같이 연결 될 것이다. 

그림만 봐서는 매우 간단해 보인다. 하지만, 실제로 WebRTC 로 통신하기 위해서는 시그널링 서버를 구축해야 한다. 시그널링 서버에 대해서는 2.4장에서 설명하겠다.


2.3.2 WebRTC 사용해야 하는 경우. 

WebRTC 는 어떤 경우에 사용하면 좋을까? 가벼운 마음으로 구글 문서를 읽어보자. 


구글 문서(https://cloud.google.com/architecture/gpu-accelerated-streaming-using-webrtc?hl=ko#when_to_use_webrtc)를 인용해보겠다. 


WebRTC는 클라이언트 웹브라우저에 대한 지연 시간을 줄이는 것이 애플리케이션에 가장 중요할 때 가장 효과적입니다. 영상 채팅 및 다자간 통화 소프트웨어가 가장 일반적인 사용 사례에 포함됩니다. 사전 레코딩 또는 렌더링되는 동영상 콘텐츠 제공과 같이 지연 시간이 용인되는 스트리밍의 경우에는 WebRTC가 덜 효과적입니다. WebRTC의 H.264 프로필은 무손실 인코딩을 지원하지 않습니다. 무손실 포맷이 필요한 경우 Teradici의 PCoIP와 같은 다른 솔루션을 고려해야 합니다.


WebRTC 사용 목적은 다음과 같습니다.  

- 브라우저 또는 휴대기기에 대한 짧은 지연 시간의 오디오 및 동영상 제공

- 바이너리 데이터 또는 키보드, 마우스, 게임 패드 입력과 같은 이벤트의 지연 시간이 짧은 스트리밍

- 브라우저 또는 휴대기기에 대한 게임 스트리밍


다음과 같은 목적으로는 WebRTC를 사용하지 않습니다.  

- 사전 녹화된 미디어나 렌더링된 미디어의 대규모 배포

- 최신 브라우저에서 지원되지 않는 동영상 형식 스트리밍

- 이전 브라우저와의 호환성



WebRTC는 실시간으로 동영상 및 오디오를 지연 없이 전송하기 위해서 주로 사용하지만, 게임 스트리밍에서도 사용한다는 것을 알 수 있으며, 심지어는 IoT 에 활용이 되고 있다. 다양한 목적으로 WebRTC 를 사용할 수 있는데, 상세한 내용은 지난번 글의 1.9장에서 상세하게 소개했었다. 


[TO.주니어 개발자] WebRTC 개요 정리



2.4 시그널링, WebRTC 프로토콜

2.4.1 시그널링이란? 시그널링 서버가 필요한 이유?


시그널링은 통신 조정의 프로세스이다. WebRTC 어플리케이션이 'call'을 초기화하기 위해서 클라이언트가 정보를 교환한다. (이해가 잘 되는가? ㅠㅠ 이해하기 쉽지 않다..) 


시그널링 서버는 도대체 왜 필요할까? 좀 더 쉽게 생각해보자. 이미 눈치를 챈 개발자가 있을 것이다. WebRTC 는 Peer 간에 직접 데이터를 주고받는다. Peer To Peer 통신으로, 실시간으로 데이터를 전송할수 있기 때문에, 지연없는 빠른 통신이 가능하다. 하지만, 한가지 의문이 생길 것이다. 


상대방 주소를 어떻게 알 수 있을까? 


상대방의 주소를 이미 알고 있다면(또는 주소를 어딘가에 기록해놨다면) P2P로 직접 통신이 가능할 것이다. 하지만, 상대방의 주소를 모르면 절대로, 서로 통신을 할수가 없다.


상대방의 정보를 어딘가로부터 전달 받아야 하는데, 이런 이유로 인해서 시그널링 서버를 별도로 구축해야 한다. 물론, 시그널링 서버는 상대방 주소를 전달받는 역할 외에, 다양한 기능을 수행하게 된다.

시그널링 서버에 대해서는, WebRTC 스펙에 상세한 가이드가 없다. (가이드가 없어서) 시그널링 서버를 구축하는 것은 애매하고 어려운 작업이 될 것이다. 시그널링 서버는 상대방의 접속 정보 또는 영상 코덱 정보 등을 실시간으로 전달해야하며, 접속이 끊겼을 때도 상대방이 접속이 끊겼다는 알림을 전달해줘야 한다. 즉, 이게 무슨 의미냐면, 시그널링하는 과정은 클라이언트와 시그널링 서버 사이에 양방향 통신을 실시간으로 해야한다. 그래서, 일반적으로(항상 그렇지는 않지만) 클라이언트와 시그널링서버 의 통신은 WebSocket 으로 구축하는 경우가 많을 것이다. 


혹시, 위 내용이 이해가 되었는가? 


필자의 글이 더이상 이해가 안된다면... 

필자의 글을 그만 읽고, WebRTC 관련 문서를 찾아보길 바란다. 설명하기 너무 어렵다...


추후 필자가 시간이 된다면, 3장에서 시그널링 서버를 구축하는 것을 포스팅 하겠다. 필자에게 익숙한 스프링부트 환경에서 WebSocket 서버를 구축할 것이다. 참고로, 굳이 스프링은 아니어도 된다. Node.js 서버로 구현해도 되고, Go 서버로 구현해도 된다. 스프링, Node.js, Go 등 구현 기술은 크게 중요하지 않다. 더 중요한 사실은 클라이언트와 시그널링 서버 사이에 시그널링 하는 프로세스가 매우 중요하며, 어떤 데이터를 주고받는지 이해하고 설계하는 것이 중요하다. SDP 프로토콜에 의한 offer, answer 를 주고받는 과정을 수행한다. (매우 중요한 내용이다.)


다시 한번 말하지만, 시그널링 서버에 대한 명확한 가이드가 존재하지 않는다. 필자는 웹소켓으로 구현하였지만, 아래 글 읽어보면, 시그널링 서버를 웹소켓이 아닌 폴링 또는 SSE 로 구현한 사례가 있다.

https://www.html5rocks.com/ko/tutorials/webrtc/infrastructure/



2.4.2 SDP(Session Description Protocol)

2장에선 생략.. 3장에서 설명하겠다.


2.4.3 STUN, TURN 

2장에선 생략.. 3장에서 설명하겠다.


[TO.주니어 개발자] 시그널링 (WebSocket) 서버 직접 구축해보기


2.5 WebRTC API

https://developer.mozilla.org/ko/docs/Web/API/WebRTC_API


2.5.1 RTCPeerConection

- RTCPeerConnection : WebRTC 어플리케이션이 Peer 간의 연결을 생성하고 오디오와 비디오의 통신에 사용되는 API


2장에선 생략.. 3장에서 설명하겠다.


[TO.주니어 개발자] WebRTC API 정리


2.6 비디오 코텍

2장에선 생략.. 3장에서 설명하겠다.

https://developer.mozilla.org/en-US/docs/Web/Media/Formats/WebRTC_codecs


[TO.주니어 개발자] H.264, VP8 코덱 조사하기


2.7 WebRTC 라이브러리

WebRTC는 계속 발전하고 있고, 각 브라우저마다 지원 수준이 다르다. 호환성을 위해서 Google에서 제공하는 adapter.js 라이브러리를 사용하는 것을 추천한다. 

https://developer.mozilla.org/ko/docs/Web/API/WebRTC_API#%EC%83%81%ED%98%B8_%EC%9A%B4%EC%9A%A9%EC%84%B1

https://github.com/webrtcHacks/adapter


[TO.주니어 개발자] 브라우저 WebRTC 지원 현황 조사하기


안드로이드 및 iOS 에서 사용가능한 라이브러리도 존재한다. 



2.99 글 급하게 마무리

글을 급하게 마무리하겠다... WebRTC 에 대한 상세한 내용은 빠져있고, WebRTC 가 뭔지에 대해서 소개하는 허접한 글이 되었다. 시간 관계상 이정도로 대충 마무리하고... 


다음 글은 미정입니다. 


다음 글에서는,  "3. WebRTC 심화 및 시그널링 서버 구축(스프링부트 기반의 WebSocket 서버)" 라는 주제로 글을 작성하겠다...





2022.12 내용 추가 

제가 WebRTC 관련 주제로 if kakao 2022 에서 기술세션 발표를 하였습니다. 비록, 기초적인 내용이라서 WebRTC 를 잘 아는 분들에게 도움은 안되겠지만, WebRTC 를 처음 접하는 개발자 또는 실시간 커뮤니케이션 서비스에 관심이 있는 개발자에게는 조금이나마 도움이 될 것입니다. 한번 보시길 바랍니다. 

https://www.youtube.com/watch?v=8jryUH6xmjU


브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari