-
Notifications
You must be signed in to change notification settings - Fork 1
WebRTC에 대해서 알아보자
Sunny edited this page Dec 3, 2024
·
1 revision
WebRTC는 웹 환경에서 실시간 통신을 지원하는 W3C 표준 기술
주로 P2P 기반으로 동작하며, 비디오 통화, 음성 통화, 파일 공유 등 다양한 실시간 통신 애플리케이션에서 사용된다.
-
MediaStream API
- 사용자 디바이스의 카메라, 마이크 등 입력 장치에 접근하여 미디어 데이터를 가져온다.
- 예:
navigator.mediaDevices.getUserMedia()
로 스트림을 캡쳐
-
RTCPeerConnection API
- Peer 간 안정적이고 효율적인 P2P 연결을 설정하고 관리한다.
-
ICE 후보
,STUN/TURN 서버
를 활용해 네트워크 연결을 설정한다.
-
RTCDataChannel API
- Peer 간의 데이터 전송을 지원하며,
낮은 지연 시간
으로 파일이나 메시지를 교환한다.
- Peer 간의 데이터 전송을 지원하며,
NAT는 사설 네트워크(Private Network)에 속한 여러 기기들이 하나의 공인 IP를 통해 인터넷에 접속할 수 있게 해주는 방식
개인 IP를 그대로 노출하게 되면 외부공격에 노출이 되기 쉽기 때문에 자신의 개인 IP를 노출하는 대신 공인 IP를 외부에 노출한다.
NAT는 이때 Private IP를 Public IP로 1대1 대응시켜 변환하는 장치이다.
- 보안: 개인 IP를 외부에 직접 노출하지 않아 보안성 향상
- IP 주소 절약: 여러 기기가 하나의 공인 IP를 공유
WebRTC는 P2P 통신을 위해 각 Peer의 공인 IP 정보가 필요하다. 하지만 NAT 환경에서는 실제 통신 가능한 주소를 알아내기가 어렵다. 이 문제를 해결하기 위해 STUN/TURN 서버
가 필요한 것이다.
- 받은 공인 IP를 가지고 개인을 식별할 수 있는 IP로 바꾸고 연결가능한 공인 IP, 프로토콜, 포트 등을 다시 사용자에게 전달 해주는 서버
- NAT 뒤에있는 클라이언트의 공인 IP와 포트정보, 프로토콜을을 확인
- 확인된 정보를 클라이언트에게 전달
- NAT 보안 정책이 너무 엄격하거나 NAT 순회를 하기 위해 필요한 NAT 바인딩을 성공적으로 생성할 수 없는 경우에 사용. 중계 서버 역할을 수행.
- 일반적으로 STUN 프로토콜로 자신의 정보를 알아낼 수 없을때 사용
- 모든 트래픽이 TURN 서버를 거치므로 대역폭 비용이 발생.
- STUN, TURN 서버를 이용해서 획득했던 IP 주소와 프로토콜, 포트의 조합으로 구성된 연결 가능한 네트워크 주소들을 후보(Candidate)라고 부름
- NAT (공인 IP를) 받아서 STUN 혹은 TURN서버에서 IP주소와 프로토콜, 포트를 얻어서 연결 가능한 네트워크 주소들을 얻는 이 모든과정은 ICE 프레임워크에서 이루어짐
- 다양한 네트워크 경로를 탐색하여 가장 적합한 경로를 선택하는 WebRTC의 핵심 프레임워크.
- 사설IP, 공인 IP, 포트넘버 등의 정보를 가지고 있고, 그 정보를 바탕으로 가장 적합한 경로를 선택
- ICE는 로컬 IP, STUN/TURN을 통해 획득한 공인 IP를 후보군(Candidates)으로 설정
-
ICE의 동작 과정
- 각 Peer는 가능한 모든 네트워크 경로(로컬/공인 IP)를 찾는다.
- STUN/TURN 서버를 통해 공인 IP와 포트를 획득한다.
- 후보 경로(Candidate)를 탐색하며 P2P 연결을 시도한다.
- 최적의 경로가 선택되면 데이터 통신을 시작한다.
브라우저에서 사용자의 디바이스(카메라, 마이크)에 접근하여 미디어 데이터를 가져온다.
navigator.mediaDevices.getUserMedia({ video: true, audio: true })
시그널링은 Peer 간 네트워크 정보와 미디어 정보를 교환하는 과정으로, WebRTC 표준에는 포함되지 않으며 별도의 서버를 사용해야 한다.
시그널링 서버 역할
- 네트워크 주소 공유(NAT 문제 해결)
- SDP를 사용해 미디어와 연결 정보를 교환
- STUN/TURN 서버 정보 전달
SDP는 미디어 스트림 정보(코덱, 포맷, 해상도 등)와 네트워크 정보를 포함한 메타데이터
자세한 사항 : (링크)
ICE는 Peer 간 가능한 네트워크 경로를 탐색하며, 최적의 경로를 선택
- 로컬 IP 후보군 생성.
- STUN/TURN 서버로 공인 IP 후보군 추가.
- Peer 간 경로 연결 시도.
- ICE 후보가 설정되면, RTCPeerConnection을 통해 연결이 수립
- 이후 데이터 전송 및 미디어 스트림이 활성화
- 두 단말이 서로 1:1 통신하는 방식.
- 처음에 연결 단계에서만 서로의 정보를 중계하는 과정에서 부하가 발생한다.
- peer간 연결이 완료된 후에는 서버에 별도의 부하가 없다.
- 실시간성이 보장되고 서버 자원이 적게 든다.
- 하지만 N:N 혹은 N:M 연결에서 서로의 연결이 기하급수적으로 연결이 늘어나기 때문에 클라이언트의 과부하가 급격하게 증가한다.
- 종단 간 미디어 트래픽을 중계하는 중앙 서버 방식
- 클라이언트간의 연결이 아닌, 서버와 클라이언트 간의 peer를 연결한다.
- 1:1, 1:N, N:N 혹은 N:M 등 모든 연결 형식에서 클라이언트는 연결된 모든 사용자에게 데이터를 보낼 필요없이 서버에게만 자신의 영상 데이터를 보내면 된다.
- 하지만 받는 데이터는 peer수와 동일하게 유지한다.
- 1:N 형식 또는 소규모 N:M 형식의 실시간 스트리밍에 적합하다.
- 서버 비용이 아무래도 증가하고 대규모 N:M 구조에는 여전히 클라이언트가 많은 부하를 감당한다.
- 다수의 송출 미디어를 중앙 서버에서 혼합(muxing) 또는 가공(transcoding)하여 수신측으로 전달하는 중앙 서버 방식
- 클라이언트간의 연결이 아닌, 서버와 클라이언트 간의 peer를 연결한다.
- 모든 연결 형식에서 클라이언트는 연결된 모든 사용자에게 데이터를 보낼 필요없이 서버에게만 자신의 영상 데이터를 보내면 된다.
- 모든 연결 형식에서 클라이언트는 연결된 사용자의 수와 상관없이 서버에게서 하나의 peer로 데이터를 받으면 된다.
- 클라이언트의 부하가 매우 줄어든다.
- 하지만 실시간성이 저해되는 단점이 있고, video와 audio를 결합하는 과정에서 비용이 많이 든다.
- P2P 기반으로 서버를 거치지 않으므로 지연 시간이 낮다
- 브라우저에서 바로 실행 가능해서 소프트웨어나 플러그인이 필요없다
- 오디오, 비디오, 데이터와 같이 다양한 멀티미디어 전송이 모두 가능하다
- 제한적인 네트워크 환경에서 TURN 사용이 반드시 필요하다
- 다수의 Peer 연결 시 트래픽 부담이 증가한다
- 시그널링, NAT 등의 구현이 까다롭고 동작 원리가 복잡하다
용어 | 설명 |
---|---|
MediaStream | 사용자 장치(카메라, 마이크)에서 캡처된 오디오와 비디오 스트림을 표현하는 객체. |
Track | MediaStream의 구성 요소로, 개별 오디오 또는 비디오 트랙을 나타냄. |
GetUserMedia | 브라우저에서 사용자 장치(마이크, 카메라)에 접근하기 위한 API. |
RTCPeerConnection | WebRTC의 핵심 객체로, Peer 간의 오디오, 비디오, 데이터 전송을 관리. |
ICE Candidate | Peer가 사용할 수 있는 네트워크 경로의 집합. |
DTLS (Datagram Transport Layer Security) | WebRTC에서 데이터 암호화를 위해 사용하는 프로토콜. |
SRTP (Secure Real-Time Protocol) | 오디오와 비디오 데이터를 암호화하여 전송. |
SCTP (Stream Control Transmission Protocol) | WebRTC 데이터 채널에서 신뢰성 있는 데이터 전송을 지원하는 프로토콜. |
RTP (Real-Time Protocol) | 실시간 오디오 및 비디오 전송을 위한 프로토콜. |
RTCP (Real-Time Control Protocol) | RTP 스트림의 품질 모니터링을 위한 제어 프로토콜. |
RTPCapabilities | 브라우저나 장치가 지원하는 코덱과 RTP 관련 기능을 정의하는 객체. |
- Mediasoup 포트 매핑 문제
- swagger 같은 응답 코드에 다양한 응답 보여주기
- Sudo가 계속 비밀번호를 요청함
- Docker 이미지가 너무 크다
- Git action에서 도커 이미지 빌드 시간을 단축시켜보자
- Docker compose를 이용해서 메모리 사용률을 줄여보자
- 방송 녹화 시 CPU 과부하 문제를 해결해보자
- Release 브랜치? 너 필요해?
- 로딩이 너무 짧아…!
- NestJS ORM으로 무엇을 사용해야 할까?
- WebRTC를 이용한 1:N 스트리밍 서비스에서 시그널링 서버가 필요할까?
- 실시간 채팅 구현: 인메모리 방식을 선택한 이유
- MySQL 아키텍처 개선: DB 의존성 분리와 서버 역할 명확화
- 브라우저 창이 최소화되면 비디오 송출이 안된다…!
- Mediasoup 기본 개념
- DLTS와 Signaling
- Tell, Don't Ask (TDA) 원칙이란
- VPC(Virtual Private Cloud) 학습 정리
- 순환참조: A 서비스 ‐ B 서비스 vs. A 서비스 ‐ B 레포지토리
- Dto 메서드 전략
- WebRTC란?
- 자바스크립트 패키지 매니저(npm, yarn, pnpm)
- shadcn/ui을 이용해 UI 개발 생산성 높이기
- React 이벤트 핸들러 네이밍(on vs handle)
- React-router-dom의 createBrowserRouter을 사용해보기
- fetch vs axios