[리액트] webRTC

Jang Seok Woo·2022년 4월 11일
0

리액트

목록 보기
54/58

항해99와 함께한 마지막 실전 프로젝트

티밍 바로가기

프로젝트에서 가장 신경쓰고 익히기 위해 애쓴 webRTC를 어떻게 이해하고 사용했는지 정리해보도록 하겠다.


WebRTC(=Web Real Time Communication)

웹/앱에서 별다른 소프트웨어없이 카메라, 마이크 등을 사용해서 실시간 커뮤니케이션을 제공해주는 기술입니다.

웹 상에서 일어나는 실시간 커뮤니케이션 기술이라고 생각하면 된다. 다만 서버같은 중간자 없이 브라우저 간에 직접 오디오나 비디오를 스트림하고, 그 외에 데이터들도 교환할 수 있는 기술이다.

Peer to Peer 방식

Peer to peer 방식은 동등 계층간의 통신방식으로 클라이언트와 서버의 개념없이 동등한 노드들로 구성되어 데이터를 주고받는 형식을 말합니다.

STUN/TURN server

저희가 구현한 WebRTC는 peer-to-peer로 작동하게 디자인되어있기 때문에 사용자들은 direct route로 연결이 가능합니다.

하지만 방화벽이 존재하거나 NAT 환경에 놓여 있는 경우에는 각 Peer에 대한 직접적인 시그널링이 불가능합니다.

따라서 클라이언트는 자신의 Public IP를 확인하기 위해 STUN 서버로 요청을 보내고 서버로 부터 자신의 Public IP를 할당받습니다.

이후, Public 망에 존재하는 TURN 서버를 경유하여 통신하게 됩니다.

저희는 STUN 서버는 단순한 중계 서버라 판단해 구글에서 제공하는 STUN서버를 사용하였습니다

저희 프로젝트에서의 webRTC동작에 대해 설명드리겠습니다.
프로젝트룸에 참여시, 소켓IO의 연결 이벤트가 발생하고, 백엔드로부터 해당 프로젝트룸에 소켓IO의 기능인 join을 통해, 유저의 데이터를 룸소켓에 포함시킵니다.

이후 Join이 승인된 유저에게 데이터를 보내주기 위해,
방에 있던 유저들의 포트폴리오 정보를 백엔드의 mongoDB에서 데이터를 가져오게되고,
프론트엔드에선 소켓으로 전달받은 데이터 정보를 이용하여, 영상통화를 위한 peerconnection 구축 및 유저의 포트폴리오 뷰를 구성합니다.

브라우저 호환성

WebRTC는 아직까지 다양한 플랫폼에서 표준화가 완전히 구현되지는 않은 기술이라고 한다. 정확히 이야기하자면 WebRTC 자체는 1.0 버전의 표준이 있지만, 이 규격을 모두 준수하는 플랫폼들이 아직까지 많지 않다. 따라서, webrtc github에서 제공하는 adapter.js 라이브러리를 함께 사용해야한다.

WebRTC의 보안?

Encryption은 모든 WebRTC 컴포넌트에 필수적. JavaScript APIs는 secure origin(HTTPS, localhost)에서만 사용 가능.

ICE(Interactive Connectivity Establishment)와 Candidate

위의 STUN, TURN 등으로 찾아낸 연결 가능한 네트워크 주소들을 Candidate(후보)라고 할 수 있다.
ICE라는 프레임워크에서 Finding Candidate(후보 찾기)를 한다.
보통 3종류의 후보들을 갖게되는데, 그 종류는 아래와 같다.

[Direct Candidate] Local Address : 클라이언트의 사설 주소(Host Candidate), 랜과 무선랜 등 다수 인터페이스가 있으면 모든 주소가 후보가 됨
[Server Reflexive Candidate] Server Reflexive Address : NAT 장비가 매핑한 클라이언트의 공인망 주소로 STUN에 의해 판단한다.
[TURN relay Candidate] Relayed Address : TURN서버가 패킷 릴레이를 위해 할당하는 주소

즉, ICE는 (2개의) peer끼리 P2P 연결을 가능하게 하도록 최적 경로를 찾아주는 프레임워크다.

SDP(Session Description Protocol)

ICE를 통해 우리는 확실히 P2P 통신을 할 수 있는 주소 후보들을 찾았다. 이제 정보들을 서로 주고받게 만들어줘야 하는데, 이 때 쓰이는 것이 SDP다.

SDP(Session Description Protocol)는 WebRTC에서 스트리밍 미디어의 해상도나 형식, 코덱 등의 멀티미디어 컨텐츠의 초기 인수를 설명하기 위한 프로토콜이다. 비디오의 해상도, 오디오 전송 또는 수신 여부 등을 송수신 할 수 있다.

이처럼 미디어와 관련된 초기 세팅 정보를 기술하는 SDP는 응답 모델(Offer/Answer)을 갖고 있다고 한다.

어떤 피어가 이러한 미디어 스트림을 교환할 것이라고 제안을 하면, 상대방으로부터 응답이 오기를 기다린다는 의미

각자의 peer가 수집한 ICE 후보 중에서 최적의 경로를 결정하고 협상하는 프로세스가 발생하고 수집한 ICE 후보들로 패킷을 보내 가장 지연 시간이 적고 안정적인 경로를 찾는다.

최적의 ICE 후보가 선택되면, 기본적으로 필요한 모든 메타 데이터와 IP 주소 및 포트, 미디어 정보가 피어 간 합의가 완료된다.

각 피어에 의해 로컬 데이터 스트림의 엔드포인트가 생성되며, 이 데이터는 양방향 통신 기술을 사용하여 최종적으로 양방향으로 전송된다.

NAT의 보안 이슈 등으로 최선의 ICE 후보를 찾지 못할 경우

이때에는 폴백으로 세팅한 TURN 서버를 P2P 대용으로 설정한다.

통신에 TURN 폴백을 사용할 때 각 피어는 굳이 귀찮게 P2P로 데이터를 연결하고 전송하는 방법을 알 필요가 없다. 대신, 통신 세션 중에 실시간 멀티미디어 데이터를 중개하는 공용 TURN 서버를 알고 있어야한다.

Trickle ICE(물방울 ICE)

일반적으로 각 peer들은 ICE 후보들을 수집해서 그 목록을 완성한 후 한꺼번에 교환하게 된다.

하지만 이러한 방식은 SDP의 제안 응답 모델과 맞물리면서 단점으로 작용한다.

후보를 모으는 데에도 시간이 오래 걸리고, 그 과정에서 네트워크 환경에 따라 지연이 될 수 있다.

또, 한 쪽 peer의 ICE 후보 수집 작업이 완료되어야만 다른 peer가 ICE 후보를 모을 수 있기 때문에 비효율적이라고 한다.
(동기적)

이러한 비효율적인 후보 교환 작업을 병렬 프로세스로 수행할 수 있게 만드는 것이 바로 Trickle ICE다.

두 개의 peer들이 ICE 후보를 수집하고 교환하는 과정을 동기적 프로세스에서 비동기적 프로세스로 만드는 기술이라고 할 수 있다.

즉, Trickle 옵션이 활성화된 ICE 프레임워크는 각 peer에서 ICE 후보를 찾아내는 그 즉시 교환을 시작한다.

그래서 상호 간 연결 가능한 ICE를 보다 빨리 찾아낼 수 있다. 이러한 옵션 덕분에 ICE 프레임워크는 피어 간의 연결 상태를 체크함과 동시에 연결에 걸리는 시간을 최적화할 수 있다. 결론적으로 Trickle 옵션은 가능하다면 활성화하는 게 좋다고 한다.

Signalling

위의 설명한 일련의 과정을 시그널링이라고 한다. 시그널링은 WebRTC 자체에서 지원하는 기능은 아니라서, 미리 준비해야 하는 과정이라고 한다.

시그널링은 WebRTC 자체의 스펙도 아니기 때문에, 한 가지로 딱 정해진 방법이 없다.

정해진 방법이 없는 이유는 알 수 없는 두 장치가 언제 어떤 방식으로 연결될 수 있는지의 모든 경우를 예측하는 것이 불가능하기 때문다.

그래서 개발자는 자신에게 맞는 최적의 방법을 선택적으로 적용해야 한다.

이 때문에 일반적으로 두 개의 장치를 연결할 수 있는 시그널링 서버를 직접 구축하거나, 시그널링 서버를 제공해주는 외부 솔루션을 적용할 수 있다.

만약 시그널링 서버를 직접 구축한다면 웹 소켓(Web Socket)이나 서버 전송 이벤트(Server-sent Event) 방법을 적용할 수 있다.

참고

시그널링 서버를 제공해주는 솔루션을 쓰는 것도 방법이 될 수 있다고 한다. 아마존의 Kinesis Video Stream 이 대표적인 예이고, 구글의 AppRTC에서는 Google App Engine으로 구현된 시그널링 서버를 확인할 수 있다.

profile
https://github.com/jsw4215

0개의 댓글