WebRTC 기본 개념 및 사용법

choko's avatar
Jun 29, 2024
WebRTC 기본 개념 및 사용법
 

WebRTC(Web Real-Time Communication)

  • WebRTC(Web Real-Time Communication)
    • Peer to Peer간 실시간 커뮤니케이션을 제공해주는 기술이다.
    • 별다른 소프트웨어 없이 다른 사용자와 실시간 채팅, 화상회의, 파일 공유 등의 서비스를 제공할 수 있다.
    • Latency가 짧고, P2P이기 때문에 서버에 부하가 줄어든다.
      • P2P를 위해 Signaling이란 과정을 거쳐야 한다.
    • 오래된 브라우저의 경우 제대로 지원이 안될수 있고, STUN/TRUN 서버가 필요하다는 단점이 있다.
      • STUN/TRUN 서버란?
        • NAT 및 방화벽을 우회하여 P2P 연결을 설정하는데 사용되는 서버이다.
        • WebRTC의 경우 ICE 프레임워크를 사용하여 P2P 연결을 설정하는데, 가능한 모든 연결 경로(candidates)를 수집하고 그 중 가장 적합한 경로를 선택한다.
        • → 클라이언트는 STUN 서버에 요청을 보내 자신의 공용 IP 주소와 포트를 확인하고, 이 정보를 ICE Candidate로 사용하여 연결을 시도한다.
         
  • 통신 API
    • MediaStream API
      • 클라이언트의 미디어 기기에 접근하기 위한 API
      • 클라이언트 카메라/오디오에 접근하는 예시 코드
        • const openCamera = async () => { const constraints = { video: true, audio: true, }; navigator.mediaDevices.getUserMedia(constraints).then((stream) =>{ userVideo.current.srcObject = stream userStream.current = stream }) };
    • RTCPeerConnection
      • 연결을 초기화하고 Peer을 연결하여 미디어스트림을 연결한다.
      • 신뢰할 수 없는 네트워크에서도 실시간 통신을 가능하게 한다.
        • const createPeer = () => { console.log("Creating Peer Connection"); const peer = new RTCPeerConnection({ iceServers: [{ urls: "stun:stun.l.google.com:19302" }], // 여기서 iceServers는 STUN 서버로, 무료로 사용할 수 있는 구글 STUN 서버를 사용한다. }); // Event peer.onnegotiationneeded = handleNegotiationNeeded; peer.onicecandidate = handleIceCandidateEvent; peer.ontrack = handleTrackEvent; return peer; };
    • RTCDataChannel
      • RTCPeerConnection 객체에서 오는 채널을 생성한다.
        • var peerConn = new RTCPeerConnection(); //establishing peer connection //... //end of establishing peer connection var dataChannel = peerConnection.createDataChannel("myChannel", dataChannelOptions); // here we can start sending direct messages to another peer
           
  • Signaling 흐름
      1. RTCPeerConnection를 통해 Peer 생성
        1. const peer = new RTCPeerConnection({ iceServers: [{ urls: 'stun:stun.l.google.com:19302' }], }); peer.onnegotiationneeded = handleNegotiationNeeded; peer.onicecandidate = handleIceCandidateEvent; peer.ontrack = handleTrackEvent;
      1. 각각의 Peer들은 Offer 객체를 생성한다. offer은 세션의 정보를 SDP 포맷으로 가지고 있다. 생성한 offer 정보를 SDP description을 포함하는 메세지로 만들고, webSocket을 통해 상대 클라이언트에게 전달한다.
        1. const offer = await peerRef.current.createOffer(); await peerRef.current.setLocalDescription(offer); sendMessage(webSocketRef.current, { offer: peerRef.current.localDescription });
      1. SDP를 교환한 Peer들은 ICE candidate들을 교환한다. candidate들이 호환된다면, 미디어는 통신을 시작한다(getUserMedia).
        1. export const addIceCandidate = async (peer, candidate) => { try { await peer.addIceCandidate(candidate); } catch (err) { console.error("Error adding ICE Candidate", err); } }; ... if (message.iceCandidate && peerRef.current) { console.log("iceCandidate", message.iceCandidate) await addIceCandidate(peerRef.current, message.iceCandidate); }
      1. SDP answer를 생성하여 상대방에게 전송한 후, Track를 등록/수신하여 video 데이터를 주고받는다.
        1. // track 발신 userStream.getTracks().forEach(track => { peer.addTrack(track, userStream); }); const answer = await peer.createAnswer(); await peer.setLocalDescription(answer); sendMessage({ answer: peer.localDescription }); // track 수신 const handleTrackEvent = (e) => { console.log("Track Event") partnerVideo.current.srcObject = e.streams[0]; };
           
           
       
      notion image
       
      ref by
Share article

Tom의 TIL 정리방