티스토리 뷰
몇 개월간 webRTC 기반의 화상 서비스 개발에 참여해왔다. 당시에 공부했던 내용을 이번 기회에 차근차근 정리해보려고 한다. 오늘 포스팅에는 주요 개념에 대한 이론만 정리해보려고 한다.
웹 브라우저와 모바일 애플리케이션이 중간 서버나 플러그인 없이 서로 직접 통신할 수 있도록 하는 표준과 프로토콜 집합이다. 오디오 및 비디오 통화를 포함한 실시간 데이터 전송을 지원하는 기술이며, P2P(Peer to Peer) 통신 모델을 사용한다.
아래 객체들을 통해 peer간 데이터 교환이 이루어지며, RTCPeerConnection 객체들이 적절하게 데이터를 교환할 수 있게 처리하는 과정을 시그널링(Signaling)이라고 한다.
- MediaStream : 카메라, 마이크 등 데이터 스트림 접근을 위한 객체 / 비디오나 오디오를 실시간으로 전송하는 기능
- RTCPeerConnection : Peer간 연결 설정 및 네트워크 상태에 따라 자동으로 최적의 경로를 선택하여 데이터 전송을 최적화
- RTCDataChannel : 두 peer간에 텍스트나 파일과 같은 데이터를 교환할 수 있게 해주는 통신 경로
시그널링(Signaling)
peer간 직접적으로 통신을 시작하기 전에 서로 필요한 연결 정보를 교환하는 과정을 의미한다.
(서로 다른 네트워크에 있는 미디어 포맷 등을 상호 연동하기 위해 협의 과정)
STUN(Session Traversal Utilities for NAT)
공개 주소(public address)를 발견하거나 peer간 직접 연결을 막는 등 라우터의 제한을 결정하는 프로토콜이다. 클라이언트는 자신의 공개 주소를 알아내고 NAT(네트워크 주소 변환) 장치 뒤에 있는 자신의 장치가 외부에서 접근 가능한지 확인한다.
즉, 클라이언트는 STUN 서버를 통해 현재 사용하고 있는 공개 주소가 무엇인지 알아낸다. 하지만 공개 주소를 발견해도 모두가 연결이 가능하지 않다. 이를 위해 TURN 서버가 필요하다.
TURN(Traversal Using Relays around NAT)
NAT 환경에서 클라이언트 간 직접 연결이 불가능할 때, 데이터 전송을 중계하는 역할을 하는 서버이다. TURN 서버를 사용하면 연결이 보장되지만, 중계 과정을 거치기 때문에 지연 시간이 늘어나고 대역폭이 더 많이 소모될 수 있다.
NAT(Network Address Translation)
내부 네트워크의 사설 IP 주소를 공개주소로 변환하여 여러 기기가 인터넷에 동시에 연결할 수 있도록 해주는 기술
Offer란, 연결을 시작하는 Peer가 상대방에게 미디어 정보를 포함한 정보를 SDP 형식으로 표현한다. 이 과정에서 Peer는 자신이 사용할 수 있는 미디어 코덱, 해상도, 비디오 및 오디오 스트림 등의 정보를 포함시킨다. Answer는 Offer에 대한 응답이다. Offer를 받은 Peer가 이에 응답하여 연결을 수락하고, 자신이 사용할 미디어 및 네트워크 설정 정보를 포함한 SDP를 제공하는 과정이다.
동작과정을 코드로 간단하게 설명하자면 아래와 같이 Peer A가 offer를 생성하여, B에게 전송한다.
...
// 현재 Peer의 로컬 미디어와 네트워크 설정을 기반으로 새로운 SDP Offer를 생성
const offer = await peerConnection.createOffer();
// 생성된 Offer를 localDescription으로 설정
await peerConnection.setLocalDescription(offer);
// Offer를 상대방 Peer B에게 전송
signalingServer.send({ type: 'offer', offer });
Offer를 수신한 Peer B는 아래 코드와 같이 Offer를 Remote Descrption로 설정하고 Answer를 생성한다. 그리고 Peer B가 생성한 Answer를 다시 A에게 전송하여 A가 해당 Answer를 Remote Descrption으로 설정하는 과정을 진행한다. (더 자세한 코드는 다음 포스팅에 정리해보려고 한다.)
if (message.type === 'offer') {
// Peer B에서 Offer를 원격 설명으로 설정
await peerConnection.setRemoteDescription(new RTCSessionDescription(message.offer));
// Peer B에서 Answer 생성
const answer = await peerConnection.createAnswer();
await peerConnection.setLocalDescription(answer);
// Answer를 시그널링 서버를 통해 Peer A에게 전송
signalingServer.send({ type: 'answer', answer });
}
ICE는 두 개의 단말이 P2P 연결을 가능하게 하도록 최적의 경로를 찾아주는 프레임워크를 말한다. ICE는 NAT이나 방화벽이 있는 환경에서도 피어 간 직접 통신을 가능하게 하기 위해 설계된 프로토콜이다.
STUN과 TURN 서버를 통해 획득한 IP 주소와 프로토콜, 포트의 조합으로 구성된 연결 가능한 네트워크 주소들을 ICECandidate라고 한다. Candidate는 두 Peer 간의 P2P 연결을 위해 사용될 수 있는 가능한 네트워크 경로를 의미한다.
1. A는 RTCPeerConnection 객체를 생성한다. RTCPeerConnection 객체는 연결 관리, 미디어 스트림 전송, ICE 후보 처리 등의 역할을 담당한다.
2. A는 RTCPeerConnection 객체의 createOffer() 메서드를 사용해 offer(SDP session description)를 생성한다.
3. A는 생성한 offer로 setLocalDescription() 메서드를 호출하여 localDescription으로 설정한다. (이 과정은 현재 세션에 대한 정보를 업데이트하고, 연결의 상태를 준비 상태로 변경한다) 그리고 offer를 B에게 보낸다.
5. B는 setREmoteDescription() 메서드를 통해 A의 offer를 설정한다.(B의 RTCPeerConnection이 A의 설정 정보를 알 수 있도록 한다)
6. B는 createAnswer() 메서드를 통해 answer(SDP session description)를 생성한다.
7. B는 생성된 answer를 setLocalDescription() 메서드를 호출하여 localDescription으로 설정한다. 그리고 생성된 answer를 A에게 보낸다.
8. A는 B의 answer를 setRemoteDescription() 메서드를 통해 remoteDescription을 설정한다.
- Total
- Today
- Yesterday