투케이2K

186. (TWOK/LOGIC) [Aws] WebRTC 기기 입장에서 peerConnection 이벤트 감지를 통해 뷰어 실시간 영상 재생 동시 접속 제한 수 관리 로직 본문

투케이2K 로직정리

186. (TWOK/LOGIC) [Aws] WebRTC 기기 입장에서 peerConnection 이벤트 감지를 통해 뷰어 실시간 영상 재생 동시 접속 제한 수 관리 로직

투케이2K 2026. 5. 9. 19:57
728x90
반응형

[로직 정리]

정리 로직 : AWS / WebRTC / peerConnection

제 목 : [Aws] WebRTC 기기 입장에서 peerConnection 이벤트 감지를 통해 뷰어 실시간 영상 재생 동시 접속 제한 수 관리 로직

 

[설 명]

// --------------------------------------------------------------------------------------
[사전) 설정 및 정보 확인 사항]
// --------------------------------------------------------------------------------------

1. 제 목 : [Aws] WebRTC 기기 입장에서 peerConnection 이벤트 감지를 통해 뷰어 실시간 영상 재생 동시 접속 제한 수 관리 로직


2. 테스트 환경 : Aws / Kvs / WebRTC


3. 사전) 👉 AWS KVS WebRTC 설명 : 

  >> WebRTC 란 웹, 애플리케이션, 디바이스 간 중간자 없이 오디오나 영상 미디어를 포착하고 실시간 스트림할 뿐 아니라, 임의의 데이터도 교환할 수 있도록 하는 기술입니다

  >> WebRTC 는 간단한 API 를 통해 웹 브라우저, 모바일 애플리케이션 및 커넥티드 디바이스 간에 실시간 통신을 활성화할 수 있습니다

  >> WebRTC 주요 용어 : 

    - SDP (Session Description Protocol) : 오디오/비디오 코덱, 해상도, 포트 등 스트리밍 정보를 담은 텍스트 포맷
    - Offer / Answer	: 통신 연결을 협상하기 위한 SDP 메시지 (초기 연결 설정)
    - ICE (Interactive Connectivity Establishment) : NAT/P2P 환경에서도 연결 가능한 경로(IP, 포트 등)를 찾기 위한 기술
    - Candidate : 가능한 연결 경로 (IP + Port 조합)

  >> WebRTC [ICE] 연결 형태 : 

    - Relayed Address : TURN 서버가 패킷 릴레이를 위해 할당하는 주소
    - Server Reflexive Address : NAT 가 매핑한 클라이언트의 공인망 (Public IP, Port)
    - Local Address : 클라이언트의 사설주소 (Private IP, Port)

  >> WebRTC STUN 및 TURN 서버 설명 : 

    - (같은 와이파이 망) STUN 서버는 HOST 를 거쳐 >> Server Reflexive Address 만을 응답하지만,
      (릴레이서버 사용) TURN 서버는 Relayed Address와 Server Reflexive Address 를 모두 응답한다
    - STUN, TURN 서버를 이용해 SDP Answer IP주소 를 취득 >> RTCPeerConnection Remote 연결 수행

  >> WebRTC SDP 오퍼 생성 (뷰어) 및 응답 (마스터) 스트리밍 플로우 : 

    [Viewer → Signaling Server] -- SDP Offer --> [Master] : 뷰어는 마스터로 스트리밍 오퍼 신호 보낸다
    [Master] -- SDP Answer --> [Viewer] : 마스터는 특정 뷰어의 오퍼 신호 확인 후 응답을 보낸다

    [Viewer] -- ICE Candidate --> [Master] : 스트리밍을 할 수 있는 경로 확인
    [Master] -- ICE Candidate --> [Viewer] : 스트리밍을 할 수 있는 경로 확인

    P2P 연결 성립 → 스트리밍 시작


4. 사전) 👉 자바스크립트 AWS Kvs WebRTC 사용 라이브러리 의존성 부여 코드 첨부 :

  <script src="https://code.jquery.com/jquery-latest.min.js"></script>-->

  <script src="https://cdnjs.cloudflare.com/ajax/libs/spin.js/2.3.2/spin.js"></script>
  <script src="https://unpkg.com/sweetalert/dist/sweetalert.min.js"></script>

  <script src="https://unpkg.com/amazon-kinesis-video-streams-webrtc/dist/kvs-webrtc.min.js"></script>
  <script src="https://sdk.amazonaws.com/js/aws-sdk-2.1416.0.min.js"></script>

// --------------------------------------------------------------------------------------






// --------------------------------------------------------------------------------------
[로직 설명]
// --------------------------------------------------------------------------------------

1. ✅ (중요) WebRTC peerConnection.connectionState 상태 간략 정리 : 

  >> peerConnection.connectionState 란 WebRTC 연결 전체 상태 (통합 상태 머신) 감지 콜백 리스너 입니다.

  >> peerConnection.connectionState 는 마스터 입장에서 뷰어의 연결 완료 여부 판단용으로 가장 적합하게 사용할 수 있습니다.

  >> peerConnection.connectionState 주요 상태 : 

    - new 상태 : PeerConnection이 생성됨 / Viewer 가 아직 접속 안 함 상태
    - connecting 상태 : 연결을 구성 중 상태 (ICE candidate 교환, ICE 후보 체크, DTLS Handshake, SRTP 세션 준비)
    - connected 상태 : Viewer 가 연결이 완료되었으며, Video/Audio 전송 시작 및 Viewer가 실제로 화면을 보기 시작
    - disconnected 상태 : 일시적으로 네트워크가 끊김 상태 (재연결 가능성 있음) / disconnected 가 발생 후 연결 된 뷰어가 종료 될 수도 있지만, 잠시 기다리면 다시 connected 로 돌아올 수 있는 상태
    - failed 상태 : 복구 불가한 연결 실패 상태 / Viewer 세션 실패 상태로 PeerConnection 재생성 필요
    - closed 상태 : PeerConnection 이 명시적으로 닫힘 상태 ( ex : pc.close(); ) / Viewer 종료 처리 완료 상태


2. 디바이스 기기는 WebRTC 객체 생성 완료 및 Viewer 의 접속 대기 준비 중 상태


3. 디바이스 기기는 signalingClient.on('sdpOffer') 이벤트 처리 부분에서 peerConnection 이벤트 감지 리스너 생성 및 실제 WebRTC 에 연결 요청 온 뷰어 접속 관리 수행

  // ✅ Viewer 연결 객체 관리를 위한 전역 변수 선언
  const peerConnections = new Map();
  const MAC_CONN_USER = 2; // 뷰어 최대 접속 가능한 사용자 수 정의


  // ✅ [Viewer 의 SDP Offer 수신 대기]

  signalingClient.on('sdpOffer', async (offer, remoteClientId) => {

    // [RTCPeerConnection 만들기]
    const peerConnection = new RTCPeerConnection(config); 

    // [미디어 스트림 추가]
    localStream.getTracks().forEach(track => peerConnection.addTrack(track, localStream)); // [카메라 스트림 트랙에 추가]

    // [peerConnection remoteClientId 지정]
    peerConnection.onicecandidate = event => {
        if (event.candidate) {
            signalingClient.sendIceCandidate(event.candidate, remoteClientId);
        }
    };
              
    // [상대방 오퍼를 내 Remote 에 추가]
    await peerConnection.setRemoteDescription(offer);

    // [Answer 옵션 지정 및 생성]
    const answer = await peerConnection.createAnswer();

    // [Answer 를 내 local 로 저장]
    await peerConnection.setLocalDescription(answer);


    // --------------------------------------------
    // ✅ [RTCPeerConnection 해제 상태 감지를 위한 이벤트 리스너 등록]
    // --------------------------------------------
    // [클로저로 remoteClientId 캡처] : 다중 뷰어 상태 동시 감지
    // --------------------------------------------
    (function(id) {

        peerConnection.onconnectionstatechange = () => {
            console.log(`peerConnection.connectionState 뷰어 Client ID : ${id}`);

            if (peerConnection.connectionState === 'connected') { // 연결 완료 된 상태                
                console.log('[peerConnection Connection Viewer] : [connected]');

                if (peerConnections.size >= MAC_CONN_USER){ // 최대 사용자 인 경우
                                    
                  peerConnections.delete(id); // ✅ 뷰어 삭제 수행

                  peerConnection.close(); // 뷰어 연결 종료 처리

                }
                else {
                  peerConnections.set(id, peerConnection); // ✅ 뷰어 추가 수행

                  // ✅ [SDP Answer 응답 전송]              
                  signalingClient.sendSdpAnswer(peerConnection.localDescription, remoteClientId); // [접속 시도한 기기 아이디를 지정해 줘야함]
                }                
            }


            if (peerConnection == null
                || peerConnection.connectionState === 'disconnected'
                || peerConnection.connectionState === 'failed'
                || peerConnection.connectionState === 'closed') { // 피어 연결 해제 상태 감지

                console.log('[peerConnection Connection Viewer] : [disconnected]');

                // [여기서 리소스 정리 및 UI 업데이트]
                try {
                    peerConnections.delete(id); // ✅ 뷰어 삭제 수행
                }
                catch (error) {
                    console.error("[peerConnection.onconnectionstatechange] : [Exception] : ", error.message);
                }

            }

        };

    })(remoteClientId)

  });

// --------------------------------------------------------------------------------------






// --------------------------------------------------------------------------------------
[참고 사이트]
// --------------------------------------------------------------------------------------

▶️ [업무 이슈] AWS Kvs WebRTC 뷰어 실시간 영상 재생 시 동시 접속 제한 수 초과로 시청자가 접속 가능한 이슈 문의

https://kkh0977.tistory.com/8799

https://blog.naver.com/kkh0977/224274834112


▶️ [Aws Kinesis Video Streams] WebRTC peerConnection.connectionState 뷰어 연결 상태 감지 설명

https://kkh0977.tistory.com/8782

https://blog.naver.com/kkh0977/224260331927


▶️ [android] 안드로이드 AWS KVS WebRTC 실시간 비디오 재생 뷰어 로직 정리 - google-webrtc

https://kkh0977.tistory.com/8771

https://blog.naver.com/kkh0977/224254825523


▶️ [Aws Kinesis Video Streams] IceServer ICE 서버 리스트 와 ICE_CANDIDATE ICE 캔디 데이트 설명 정리

https://kkh0977.tistory.com/8772

https://blog.naver.com/kkh0977/224254833429


▶️ [Aws Kinesis Video Streams] WebRTC onSignalingChange PeerConnection 내부의 SDP 상태 설명

https://kkh0977.tistory.com/8781

https://blog.naver.com/kkh0977/224260325153


▶️ [기능 개선] 자바스크립트 aws kvs webRtc 디바이스 마스터 영상 송출 시 뷰어 다중 접속 설정 - Multi PeerConnection

https://kkh0977.tistory.com/8057

https://blog.naver.com/kkh0977/223898870074?trackingCode=blog_bloghome_searchlist


▶️ [Web/JavaScript] AWS Kvs WebRtc 마스터 비디오 스트림 다중 뷰어 영상 송출

https://kkh0977.tistory.com/8058

https://blog.naver.com/kkh0977/223899701921?trackingCode=blog_bloghome_searchlist

// --------------------------------------------------------------------------------------
 
728x90
반응형
Comments