본문 바로가기
websocket & webRTC

3. RTCPeerConnection 이해와 관련된 주요 인터페이스

by spare8433 2025. 4. 22.

1. RTCPeerConnection

RTCPeerConnection은 WebRTC(Web Real-Time Communication) 기술의 핵심 구성 요소로, 웹 브라우저 간 피어-투-피어(P2P) 연결을 설정하고 관리하는 JavaScript API입니다.



1.1 주요 속성

// 전체 연결 상태 ('new', 'connecting', 'connected', 'disconnected', 'failed', 'closed')
pc.connectionState

// ICE 연결 상태 ('new', 'checking', 'connected', 'completed', 'failed', 'disconnected', 'closed')
pc.iceConnectionState

// ICE 후보 수집 상태 ('new', 'gathering', 'complete')
pc.iceGatheringState

// 시그널링 프로세스 상태 ('stable', 'have-local-offer', 'have-remote-offer', 'have-local-pranswer', 'have-remote-pranswer', 'closed')
pc.signalingState

pc.localDescription        // 로컬 피어의 SDP
pc.remoteDescription       // 리모트 피어의 SDP





1.2 주요 메서드

// RTCPeerConnection 연결 설정 메서드
pc.createOffer([options])              // 로컬 SDP 제안 생성
pc.createAnswer([options])             // 원격 제안에 대한 SDP 응답 생성
pc.setLocalDescription(description)    // 로컬 세션 설명 설정
pc.setRemoteDescription(description)   // 원격 세션 설명 설정
pc.addIceCandidate(candidate)          // 원격 ICE 후보 추가
pc.restartIce()                        // ICE 연결 재시작
pc.close()                             // RTCPeerConnection 연결 종료

// RTCPeerConnection 미디어 관련 메서드
pc.addTrack(track, stream...)          // 미디어 트랙 추가 (송신용)
pc.removeTrack(sender)                 // 이전에 추가한 트랙 제거
pc.getTransceivers()                   // 모든 트랜시버 목록 반환
pc.addTransceiver(trackOrKind[, init]) // 새 트랜시버 추가
pc.getSenders()                        // 모든 RTCRtpSender 객체 반환
pc.getReceivers()                      // 모든 RTCRtpReceiver 객체 반환

// RTCPeerConnection 데이터 채널 메서드
pc.createDataChannel(label[, options]) // 데이터 채널 생성





1.3 주요 이벤트

pc.onconnectionstatechange      // 연결 상태 변경 시 발생
pc.oniceconnectionstatechange   // ICE 연결 상태 변경 시 발생
pc.ontrack                      // 원격 트랙 수신 시 발생
pc.onremovetrack                // 원격 트랙 제거 시 발생 (MediaStream 객체에서)
pc.onicecandidate               // 새로운 ICE 후보 생성 시 발생
pc.ondatachannel                // 원격 피어가 데이터 채널 생성 시 발생

// 이벤트 핸들러 사용 예시
pc.onconnectionstatechange = (event) => {
 console.log("연결 상태 변경:", pc.connectionState);
};

pc.onicecandidate = (event) => {
 if (event.candidate) {
   // 새 ICE 후보 발견
 }
};

pc.ontrack = (event) => {
 const remoteStream = event.streams[0];
 // 원격 비디오 요소에 스트림 연결
};

pc.ondatachannel = (event) => {
 const channel = event.channel;
 // 수신된 데이터 채널 처리
};










2. RTCPeerConnection 관련 주요 개념 및 인터페이스



2.1 RTCRtpSender

MediaStreamTrack이 인코딩되어 원격 피어로 전송되는 방식에 대한 세부 정보를 제어하고 얻는 기능을 제공합니다.



  • 트랙 송신: 로컬 미디어 트랙(오디오/비디오)을 원격 피어에게 전송
  • 인코딩 제어: 비트레이트, 해상도, 프레임레이트 등 송신 매개변수 조정
  • 통계 제공: 전송된 패킷, 바이트 등의 통계 정보 접근

 

// 주요 속성
sender.track          // 송신 중인 MediaStreamTrack (null일 수 있음)
sender.transport      // 사용 중인 RTCDtlsTransport 객체
sender.rtcpTransport  // RTCP 전송에 사용되는 RTCDtlsTransport

// 주요 메서드
sender.getParameters()           // 현재 인코딩 매개변수 반환
sender.setParameters(parameters) // 인코딩 매개변수 설정
sender.replaceTrack(newTrack)    // 트랙 교체 (스트림 중단 없이)
sender.getStats()                // 송신 통계 반환





2.2 RTCRtpReceiver

MediaStreamTrack에 대한 데이터 수신 및 디코딩을 관리합니다.



  • 트랙 수신: 원격 피어가 보낸 미디어 트랙 수신 및 처리
  • 디코딩 관리: 수신된 RTP 패킷을 미디어 트랙으로 변환
  • 통계 제공: 수신된 패킷, 손실률, 지터 등의 통계 정보 접근

 

// 주요 속성
receiver.track          // 수신된 MediaStreamTrack
receiver.transport      // 사용 중인 RTCDtlsTransport 객체
receiver.rtcpTransport  // RTCP 전송에 사용되는 RTCDtlsTransport

// 주요 메서드
receiver.getParameters() // 수신 매개변수 반환 (읽기 전용)
receiver.getStats()      // 수신 통계 반환





2.3 RTCRtpTransceiver

RTCRtpTransceiverRTCRtp Sender와 Receiver를 쌍으로 묶어 관리하는 고급 객체로, 특히 양방향 미디어 통신을 관리하는 데 사용됩니다.



  • 양방향 관리: 하나의 송신자(Sender)와 하나의 수신자(Receiver)를 함께 관리
  • 미디어 방향 제어: 미디어 흐름 방향 제어 (sendrecv, sendonly, recvonly, inactive)
  • 미디어 타입 관리: 특정 미디어 종류(오디오/비디오)에 대한 일관된 관리

 

// 주요 속성
transceiver.mid                 // 미디어 ID (SDP의 a=mid 값)
transceiver.sender              // 연결된 RTCRtpSender 객체
transceiver.receiver            // 연결된 RTCRtpReceiver 객체
transceiver.direction           // 원하는 미디어 방향 (sendrecv, sendonly, recvonly, inactive)
transceiver.currentDirection    // 현재 협상된 미디어 방향
transceiver.stopped             // 트랜시버가 중지되었는지 여부

// 주요 메서드
transceiver.stop()              // 트랜시버 중지 (재사용 불가)
transceiver.setCodecPreferences(codecs) // 코덱 우선순위 설정





2.4 RTCDataChannel

RTCDataChannel은 브라우저 간에 임의의 데이터를 직접 교환할 수 있게 해주는 통신 채널입니다. 오디오나 비디오 스트림과는 별개로 텍스트, 파일, 게임 데이터 등 모든 종류의 데이터를 P2P 방식으로 전송할 수 있습니다.

 

RTCDataChannel은 내부적으로 SCTP(Stream Control Transmission Protocol) 프로토콜을 사용하며, 이는 DTLS(Datagram Transport Layer Security)로 암호화됩니다.



  • P2P 데이터 전송: 서버를 거치지 않고 브라우저 간 직접 데이터 교환
  • 저지연 통신: 실시간 애플리케이션에 적합한 낮은 지연 시간
  • 다양한 전송 모드: 신뢰성 있는 전송(TCP와 유사)과 비신뢰적 전송(UDP와 유사) 지원
  • 다중 채널: 하나의 RTCPeerConnection에서 여러 개의 데이터 채널 생성 가능
  • 양방향 통신: 양쪽 피어 모두 데이터 송수신 가능
  • 바이너리 데이터 지원: 텍스트뿐만 아니라 바이너리 데이터(ArrayBuffer, Blob 등) 전송 가능

 

내부 과정

  1. RTCDataChannel API: 브라우저에서 데이터 채널 생성 및 처리
  2. SCTP (Stream Control Transmission Protocol): 메시지를 스트림으로 다루며 신뢰성, 순서 보장, 멀티채널 전송 등등 처리
  3. DTLS (Datagram TLS) 전송 데이터를 암호화하고: 무결성과 인증을 보장
  4. ICE/UDP: 피어 간 최적의 경로를 찾고, UDP를 통해 데이터를 빠르게 전송
  5. 네트워크 계층 (IP/MAC/PHY):패킷을 실제 네트워크를 통해 물리적으로 전달



// RTCDataChannel 인터페이스 주요 속성
dataChannel.id                // 채널의 고유 ID (숫자)
dataChannel.label             // 채널에 지정된 이름
dataChannel.ordered           // 메시지 순서 보장 여부 (boolean)
dataChannel.maxPacketLifeTime // 패킷 수명 제한 (밀리초)
dataChannel.maxRetransmits    // 최대 재전송 횟수
dataChannel.readyState        // 현재 채널 상태 ('connecting', 'open', 'closing', 'closed')

// RTCDataChannel 주요 이벤트 핸들러
dataChannel.onopen            // 채널이 열릴 때 발생
dataChannel.onclose           // 채널이 닫힐 때 발생
dataChannel.onmessage         // 메시지 수신 시 발생

// RTCDataChannel 주요 메서드
dataChannel.send(data)        // 데이터 전송 (문자열, Blob, ArrayBuffer 등)
dataChannel.close()           // 데이터 채널 닫기

// RTCPeerConnection에서 데이터 채널 생성
pc.createDataChannel(label, options) // 새 데이터 채널 생성





2.5 ICE (Interactive Connectivity Establishment) 와 RTCIceCandidate

ICEWebRTC에서 NAT(Network Address Translation)와 방화벽을 통과하여 두 피어 간에 직접적인 연결을 설정하기 위한 프레임워크이자 메커니즘입니다.

 

RTCIceCandidateWebRTC에서 ICE 프로토콜이 발견한 잠재적 네트워크 연결 지점을 나타내는 객체로 피어 간 RTCIceCandidate 객체를 주고받아 연결을 수립합니다.




ICE 프로세스 과정

  1. ICE 수집(Gathering): 각 피어는 가능한 모든 연결 경로(후보)를 수집
  2. 후보 교환: 수집된 후보를 시그널링 채널을 통해 상대방과 교환
  3. 연결성 확인: 모든 후보 쌍을 테스트하여 작동하는 조합 찾기
  4. 우선순위 결정: 작동하는 여러 경로 중 최적의 경로 선택



// RTCIceCandidate 읽기 전용 속성
candidate.candidate         // SDP 형식의 후보 문자열
candidate.sdpMid            // 미디어 스트림 ID
candidate.usernameFragment  // ICE 사용자 이름 조각
candidate.type              // 후보 유형 ('host', 'srflx', 'prflx', 'relay')
candidate.ip                // IP 주소
candidate.port              // 포트 번호
candidate.tcpType           // TCP 후보 유형 ('active', 'passive', 'so')
candidate.relatedAddress    // 관련 주소 (NAT 내부 주소)
candidate.relatedPort       // 관련 포트 (NAT 내부 포트)

// RTCPeerConnection에서 ICE 후보 관련 메서드
pc.addIceCandidate(candidate)  // 원격 ICE 후보 추가
pc.onicecandidate            // 새로운 ICE 후보 발견 시 이벤트
pc.onicecandidateerror       // ICE 후보 수집 오류 시 이벤트
pc.iceGatheringState         // ICE 수집 상태 ('new', 'gathering', 'complete')
pc.iceConnectionState        // ICE 연결 상태 ('new', 'checking', 'connected', 'completed', 'failed', 'disconnected', 'closed')
pc.restartIce()              // ICE 재시작