투케이2K

197. (TWOK/WORK) [업무 이슈] AWS WebRTC 뷰어 영상 통화 접속 후 SDP Answer 응답을 받지 못해 재접속 시 localStream 초기화 관련 이슈 본문

투케이2K 업무정리

197. (TWOK/WORK) [업무 이슈] AWS WebRTC 뷰어 영상 통화 접속 후 SDP Answer 응답을 받지 못해 재접속 시 localStream 초기화 관련 이슈

투케이2K 2026. 1. 1. 12:16
728x90

[제 목]

타이틀 : 투케이 / 2k / 업무 정리

제목 : [업무 이슈] AWS WebRTC 뷰어 영상 통화 접속 후 SDP Answer 응답을 받지 못해 재접속 시 localStream 초기화 관련 이슈

 


[내 용]

------------------------------------------------------------------------------
[개발 및 테스트 환경]
------------------------------------------------------------------------------

- 제 목 : [업무 이슈] AWS WebRTC 뷰어 영상 통화 접속 후 SDP Answer 응답을 받지 못해 재접속 시 localStream 초기화 관련 이슈


- 테스트 환경 : Web / Chrome / JavaScript / Aws / WebRTC / Viewer


- 사전) WebRTC 설명 : 

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

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

  >> WebRTC 주요 용어 : 

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

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

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

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

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

------------------------------------------------------------------------------





------------------------------------------------------------------------------
[이슈 사항]
------------------------------------------------------------------------------

1. 자바스크립트에서 뷰어 역할 AWS WebRTC 양방향 영상 통화 연결 수행 시 SDP 메시지 Answer 응답을 받지 못해 재접속 시 localStream 초기화 관련 이슈 발생

  >> ❌ localStream 이 정상적으로 초기화 되지 않아 스트림이 출력되지 않는 이슈 확인

  >> WebRTC 연결에 사용 된 객체 전체 초기화 (signalingClient, peerConnection, localStream 등) 관련 이슈


2. 자바스크립트 뷰어 역할 SDP Offer 전송 및 localStream 지정 코드 첨부 : 

  >> Body 비디오 객체 소스 코드 : <video autoplay="true" id="remoteView"></video>

  >> 자바스크립트 소스 코드 : 

  // 전역 변수 선언
  var localStream = null;


  // [시그널링 클라이언트 이벤트 리스너 추가]
  signalingClient.on('open', async () => {
    console.log("[signalingClient] : [open] : [Start]");


    // -----------------------------------------
    // [카메라 및 오디오 사용 권한 요청 >> 트랙 스트림 추가]
    // -----------------------------------------
    localStream = await navigator.mediaDevices.getUserMedia({ // [휴대폰 권한 요청]
        video: true,
        audio: true,
    });

    // [해당 트랙 추가로 > 마스터에게 비디오, 음성 데이터 전달]
    localStream.getTracks().forEach(track => peerConnection.addTrack(track, localStream)); // [스트림 트랙에 추가]


    // -----------------------------------------
    // ✅ [SDP 오퍼 생성 및 마스터에게 전송]
    // -----------------------------------------
    const offer = await peerConnection.createOffer({
        offerToReceiveAudio: true,
        offerToReceiveVideo: true,
    });

    await peerConnection.setLocalDescription(offer);

    signalingClient.sendSdpOffer(peerConnection.localDescription);

  });

------------------------------------------------------------------------------





------------------------------------------------------------------------------
[원인 파악 및 증상 재현]
------------------------------------------------------------------------------

1. 자바스크립트에서 뷰어 역할 AWS WebRTC 양방향 영상 통화 연결 수행 1 ~ 6 회 사이 WebRTC 연결 및 종료 반복 테스트 수행


2. 특정 시도 횟수 (ex : 4 ~ 6 회) 사이트 SDP Offer 를 보냈지만, Answer 응답을 받지 못하는 이슈 발견

  >> ❌ 특정 시간 내에 과도한 접속 및 종료 테스트 시 과도한 SDP 메시지 교환으로 내부 세션 및 객체 초기화에 문제가 발생하는 이슈


3. 해당 응답을 받지 못하는 경우 WebRTC 연결에 사용 된 객체 전체 초기화 (signalingClient, peerConnection, localStream 등) 진행

  >> 초기화 코드 : 

    // -----------------------------------------
    // [로컬 스트림도 종료 처리 수행]
    // -----------------------------------------
    localStream.getTracks().forEach(track => track.stop());


    // -----------------------------------------
    // [signalingClient close : ICE candidate 교환이나 SDP 메시지 전송이 중단]
    // -----------------------------------------
    if (signalingClient != null){

        signalingClient.close();
    }


    // -----------------------------------------
    // [peerConnection removeTrack 처리 수행]
    // -----------------------------------------
    if (peerConnection != null){

        const transceivers = peerConnection.getTransceivers?.() || [];
        transceivers.forEach(t => {
            try { if (typeof t.stop === 'function') t.stop(); } catch (e) {
                console.warn('[cleanup] transceiver.stop error:', e);
            }
        });

        const senders = peerConnection.getSenders?.() || [];
        senders.forEach(s => {
            try { peerConnection.removeTrack(s); } catch (e) {
                console.warn('[cleanup] removeTrack error:', e);
            }
        });

    }


    // -----------------------------------------
    // [peerConnection 도 연결 종료 처리 수행]
    // -----------------------------------------
    if (peerConnection != null){

        peerConnection.close(); // 미디어 스트림 종료
    }


4. 뷰어에서 WebRTC 연결 재시도 수행 및 정상적으로 SDP Answer 응답을 받았지만, 스트림이 출력되지 않는 이슈 확인

------------------------------------------------------------------------------






------------------------------------------------------------------------------
[조치 내용]
------------------------------------------------------------------------------

1. WebRTC 객체 전체 초기화 시 사용 된 객체 null 초기화 코드 추가 수행


2. 수정 된 코드 : 

    // -----------------------------------------
    // [로컬 스트림도 종료 처리 수행]
    // -----------------------------------------
    localStream.getTracks().forEach(track => track.stop());


    // -----------------------------------------
    // [signalingClient close : ICE candidate 교환이나 SDP 메시지 전송이 중단]
    // -----------------------------------------
    if (signalingClient != null){

        signalingClient.close();
    }


    // -----------------------------------------
    // [peerConnection removeTrack 처리 수행]
    // -----------------------------------------
    if (peerConnection != null){

        const transceivers = peerConnection.getTransceivers?.() || [];
        transceivers.forEach(t => {
            try { if (typeof t.stop === 'function') t.stop(); } catch (e) {
                console.warn('[cleanup] transceiver.stop error:', e);
            }
        });

        const senders = peerConnection.getSenders?.() || [];
        senders.forEach(s => {
            try { peerConnection.removeTrack(s); } catch (e) {
                console.warn('[cleanup] removeTrack error:', e);
            }
        });

    }


    // -----------------------------------------
    // [peerConnection 도 연결 종료 처리 수행]
    // -----------------------------------------
    if (peerConnection != null){

        peerConnection.close(); // 미디어 스트림 종료
    }


    // -----------------------------------------
    // ✅ [객체 null 초기화 수행]
    // -----------------------------------------
    signalingClient = null;
    peerConnection = null;
    localStream = null; 

------------------------------------------------------------------------------





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

[업무 이슈] AWS WebRTC 뷰어에서 동일한 clientId 사용해 스트리밍 시청 시 AWS 세션 초기화 이슈로 60 초내외 재사용 필요 이슈

https://kkh0977.tistory.com/8442

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


[Aws Kvs WebRTC 실시간 영상 재생 관련 구성 요소 및 용어 정리]

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


[Aws Kinesis Video Streams] WebRTC remote sender clientId 클라이언트 아이디 설명, 규격 및 제한 정리

https://kkh0977.tistory.com/8415

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


[Aws Kinesis Video Streams] WebRTC SDP 협상 과정 프로세스 정리 정리

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


[자바스크립트 AWS WebRTC 실시간 동영상 재생 수행]

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


[업무 이슈] AWS WebRTC 실시간 비디오 재생 시 Client 클라이언트 연결 접속 및 해제 상태 확인 이슈

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

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