실시간 영상 서비스를 위한 개념 정리

밍디·2022년 1월 31일
2

http

http란?
브라우저와 서버는 http를 이용하여 소통할 수 있다. 브라우저가 서버에게 http request를 보내면, 서버는 해당 요구를 확인 후, http response를 브라우저에게 보낸다.
서버는 브라우저가 요청했을 때에만 브라우저에게 무언가를 보낼 수 있다.

polling, long polling, streaming과 webSocket의 비교

https://github.com/stove-smooth/messaging/blob/main/theory/websocket.md

websocket

websocket이란?
TCP 프로토콜의 일종으로 클라이언트와 서버 사이에 지속적인 완전 양방향 연결 스트림을 만들어 주는 기술이다. websocket 프로토콜은 HTTP 폴링과 같은 반이중방식에 비해 더 낮은 부하를 사용하여 실시간 양방향 대화방식을 가능하게 한다.

작동원리
서버와 브라우저간 커넥션은 new WebSocket을 호출하며 만들어지는데 ws(or wss)라는 특수 프로토콜을 사용한다. 최초 소켓 생성 후 서버가 웹소켓 통신을 지원할 수 있다면 프로토콜을 업데이트하여 HTTP가 아닌 웹소켓 프로토콜을 사용해 서버-브라우저간 통신을 진행한다. 소켓이 정상적으로 만들어지면 다음의 이벤트를 사용할 수 있게된다.

open - 커넥션 생성
message - 데이터 수신(서버로부터)
send - 데이터 전송(서버로)
error - 에러 발생
close - 커넥션 종료

websocket의 send 메서드는 텍스트나 바이너리 데이터만 보낼 수 있다.

문제점
websocket은 서버의 메모리 파워가 중요하다. 트래픽 양이 많은 서버같은 경우에는 큰 부담이 된다.

스트리밍 프로토콜, WebRTC

스트리밍 프로토콜
실시간 영상 서비스를 위해서는 스트리밍 프로토콜을 사용해야한다. 이번 프로젝트에서는 많은 스트리밍 프토토콜 중 latency가 가장 낮은 webRTC를 사용하기로 하였다.

(트위치에서는 webRTC가 아닌 CMAF를 쓰는데, 트위치 시청자들은 지연 속도보다 고화질 화면을 중시하기 때문에 TCP 기반인 CMAF를 사용한다고 한다.)

webRTC(Web Real-Time Communication)
WebRTC는 웹 브라우저 간에 플러그인의 도움 없이 서로 통신할 수 있도록 설계된 API이다. WebRTC는 다음 구성요소를 통해 작동을 활성화한다.

  • getUserMedia: 장치에 접근하여 오디오와 비디오 미디어를 가져온다.
  • RTCPeerConnection : 피어 간 오디오, 비디오 통신을 활성화한다.
  • RTCDataChannel: 임의의 바이너리 데이터 교환을 할 수 있게한다.

webRTC를 구축하기 위해 알아야 할 개념

  • ICE(Interactive Connectivity Establishment) : ICE는 두 장치가 서로를 찾고 연결을 설정할 수 있게 대기 시간이 가장 짧은 경로를 찾을 수 있게끔 해주는 프레임워크이다. 다른 피어와 연결을 설정하려면 엔드포인트가 다른 사람과 공유할 공용 IP 주소를 알아야 한다. 웹 브라우저가 피어와 연결할 수 있도록 하는 프레임워크, 방화벽이 있는 경우, 공용 IP 주소가 없는 경우 등의 문제로 피어간 연결을 하지 못하는 경우가 있다. 이때 STUN/TURN 서버를 이용하여 이 문제를 해결한다.

  • STUN(Session Traversal Utilities for Nat) : STUN 서버는 다른 사람과 통신할 수 있는 공용 IP주소를 제공한다. 하지만 때때로 실패한다. "symmetric NAT"을 사용하는 경우에는 또다른 보안 계층을 endpoint에 더하고, IP주소뿐만아니라 port까지 바꾸어버려 연결할 수 없게한다. 이 경우 TURN 서버를 사용해야한댜.

  • TURN(Traversal Using Relays around Nat) : Peer간 직접 통신이 실패할 경우 endpoint들 사이에 데이터 릴레이를 수행하는 TURN 서버를 사용한다.
    TURN은 리소스 낭비가 크기 때문에, STUN을 수행 후 실패할 때 사용한다.

*NAT(Network Address Translate)
: IPv4의 주소 부족 문제를 해결하기 위한 방법. 사설 네트워크 주소를 사용하는 망에서 외부(공인)과의 통신을 위해 네트워크 주소를 변환하는 것. 외부 인터넷망과 연결하는 장비인 라우터에 NAT을 설정할 경우 라우터는 자신의 공인 IP주소만 외부로 알려지게 하여 내부 네트워크를 보호할 수 있는 이점이 있다.

webRTC가 연결을 생성하기 위한 방법

시그널링 서버 구축

WebRTC는 시그널링 서버 없이는 만들 수 없다. connection을 설정하기 전, 정보를 교환하기 위한 일종의 커뮤니테이션 채널이다.

  • SDP 교환
    우리가 교환해야할 정보는 SDP를 따르는 Offer와 Answer이다.
1. A가 MediaDevices.getUserMedia를 사용하여 로컬 미디어를 캡처한다.
2. A는 RTCPeerConnection을 생성하고 다른 피어로 전송될 트랙에 새 미디어 트랙을 추가하는 RTCPeerConnection.addTrack()을 호출한다.
3. A는 offer 생성을 위한 RTCPeerConnection.createOffer()를 호출한다.
4. A는 RTCPeerConnection.setLocalDescription()를 호출하여 본인의 local description으로 offer를 저장한다.
5. setLocalDescription()후에, STUN server에게 ice 후보자 생성을 요청한다.
6. A는 시그널링 서버를 사용하여 B에게 offer를 전송한다.
7. B는 offer를 받고, 이것을 RTCPeerConnection.setRemoteDescription()을 호출해 remote description으로 기록한다.
8. B는 로컬 미디어를 캡처하고 각 미디어 트랙을 RTCPeerConnection.addTrack()을 호출하여 피어 연결에 첨부한다.
9. 그 후, B는 RTCPeerConnection.createAnswer()를 호출하여 Answer를 만든다.
10. B는 RTCPeerConnection.setLocalDescription()를 호출하여 본인의 local description으로 Answer를 저장한다. 이제 B는 양쪽의 구성을 알게된다.
11. B는 시그널링 서버를 통해 A에게 Answer를 보낸다.
12. A는 Answer를 받는다.
13. A는 RTCPeerConnection.setRemoteDescription()를 호출해 remote description으로 기록한다. 이제 두 Peer 모두 구성을 알고 있고, 시작된다.
  • ICE candidate
    위에서 언급한 ICE 프로토콜을 뜻하는데, ICE candidate 등록이 중요하다.

webRTC 구현방식

[mesh]

모든 참여자가 자신의 미디어 스트림을 나머지 피어들에게 보내고,
동시에 다른 나머지 참여자들의 미디어 스트림을 모두 전달 받는 방식. 
중앙 서버 없이 p2p방식으로 직접 연결되어 소규모 인원의 미디어 교환에는 적합하지만,
사용자 수가 많아지면 문제가 발생한다.

[SFU]

중앙 서버를 통해 종단간 미디어 트래픽 중계
사용자들로부터 각각의 미디어 스트림을 받아 별도의 미디어 가공을 거치지 않고 사용자들에게 그대로 전달한다.
서버에 부하가 적게 걸리고 지연시간이 낮아 1:N스트리밍 혹은 N:N소통에 적합

[MCU]

각 참여자의 미디어 스트림을 중앙 서버에 한꺼번에 모아 가공한 후 결과물을 참여자에게 보냄. 
클라이언트의 부담이 적지만, 서버에 부하가 큼

=> SFU 방식을 선택! , 미디어 서버를 구축하자

미디어 서버 구축

미디어 서버 선택하기
https://github.com/stove-smooth/sgs-smooth/wiki/%EB%AF%B8%EB%94%94%EC%96%B4-%EC%84%9C%EB%B2%84-%EC%84%A0%ED%83%9D%ED%95%98%EA%B8%B0

#reference
[WebSocket] https://ko.wikipedia.org/wiki/%EC%9B%B9%EC%86%8C%EC%BC%93
[WebSocket] https://ko.javascript.info/websocket
[streaming-protocols] https://www.wowza.com/blog/streaming-protocols
[webRTC] https://ko.wikipedia.org/wiki/WebRTC
[webRTC] https://developer.mozilla.org/ko/docs/Web/API/WebRTC_API
[webRTC server] https://bloggeek.me/webrtc-server/
[NAT] https://namu.wiki/w/NAT
[ICE] https://developer.mozilla.org/en-US/docs/Glossary/ICE
[ICE] https://developer.mozilla.org/enUS/docs/Web/API/WebRTC_API/Protocols
[ICE, STUN,TURN] https://medium.com/swlh/webrtc-the-technology-that-powers-google-meet-hangout-facebook-messenger-and-discord-cb926973d786
[webRTC 시그널링 서버 구축]https://medium.com/monday-9-pm/%EC%B4%88%EB%B3%B4%EA%B0%9C%EB%B0%9C%EC%9E%90-webrtc-%EC%8B%9C%EA%B7%B8%EB%84%90%EB%A7%81%EC%84%9C%EB%B2%84-%EB%A7%8C%EB%93%A4%EA%B8%B0-caf8cf9adc9a
[webRTC]https://wormwlrm.github.io/2021/01/24/Introducing-WebRTC.html
[미디어서버]https://post.naver.com/viewer/postView.nhn?volumeNo=29147132&memberNo=50640104

profile
노후를 위해 꾸준히 공부하자.

0개의 댓글