WebRTC 연결 실패를 ICE 후보와 경로 통계로 진단하는 법
후보 수집, signaling 전달, 후보 쌍 검사, 선택 경로를 구분해 관측하면 WebRTC 연결 실패의 원인 후보를 좁힐 수 있습니다.
발행·오류 제보: infostoa · 편집 기준
이 글의 개별 작성자와 전문 검토자 정보는 제공되지 않습니다.
WebRTC 연결 실패는 “방화벽 문제” 하나로 진단하기 어렵습니다. 연결 경로를 만들기까지 후보 수집, 상대 후보 전달, 후보 쌍 검사, 실제 선택 경로라는 여러 단계가 있기 때문입니다. 어느 단계에서 멈췄는지 관측하면 앱의 signaling 문제와 ICE 경로 문제를 구분하는 데 도움이 됩니다. 단, 브라우저 통계는 버전과 구현에 따라 일부 항목이 비거나 제공되지 않을 수 있습니다.
먼저 실패가 재현되는 조건과 관측 시점을 고정한다
같은 실패를 비교하려면 브라우저와 버전, 운영체제, 네트워크 종류, 접속 시각, 재현 순서를 함께 기록합니다. 호출을 시작하기 전에 Chrome의 chrome://webrtc-internals를 열어두면 PeerConnection 이벤트와 통계 덤프를 보존할 수 있습니다. WebRTC 프로젝트의 버그 보고 안내는 연결 문제에서 호출 전부터 진행 중까지 이 페이지를 열고 업데이트와 통계를 내려받도록 권합니다. ICE 기능 오류에는 네이티브 로그가 필요한 경우도 있습니다.
로그에는 신호 메시지를 언제 보냈고 받았는지, 로컬·원격 description 설정 결과, 후보 이벤트와 연결 상태 변화를 시간순으로 적습니다. 화면에 “연결 중”만 보이는 자체 UI는 브라우저 내부에서 후보가 모였는지, 상대에게 전달됐는지 알려주지 않습니다. 비밀 자격증명이나 전체 SDP를 공유하지 말고, 후보 주소와 식별자가 노출되지 않도록 덤프를 제한된 경로로 다룹니다.
후보 수집이 끝났는지와 상대 후보가 전달됐는지 분리한다
먼저 iceGatheringState와 후보 이벤트를 확인합니다. 수집이 아직 진행 중이면 후보가 추가로 나올 수 있고, 완료 상태인데 후보가 없으면 ICE 서버 설정, 권한·정책, 네트워크 환경을 점검할 단서가 됩니다. 이것만으로 특정 방화벽이나 NAT가 원인이라고 단정할 수는 없습니다. 구현이 후보 주소를 감추거나 서버 반사 주소만 남기는 경우도 있어, 앱에서 관측 가능한 후보가 실제 네트워크 전체를 보여주지는 않습니다.
그 다음 signaling 경로를 별도로 확인합니다. 상대에게 전달한 후보 수, 수신한 후보 수, 메시지의 세션 식별자와 ICE 세대가 맞는지 비교합니다. trickle ICE를 쓰면 description과 후보가 서로 다른 순서로 도착할 수 있으므로, 애플리케이션이 유효한 후보를 너무 일찍 버리지 않는지 살펴야 합니다. 후보가 로컬에서 생성됐다는 사실은 상대가 이를 받았거나 연결 검사가 성공했다는 뜻이 아닙니다. 이 단계에서 수신 후보가 0이라면 우선 signaling 전달·파싱을 조사하고, 둘 다 후보를 보유한다면 다음 단계로 넘어갑니다.
후보 쌍 상태를 시간축에서 읽는다
getStats() 결과의 candidate-pair 항목은 후보 쌍 상태를 확인하는 출발점입니다. W3C 통계 Editors’ Draft에 정의된 후보 쌍 상태에는 frozen, waiting, in-progress, succeeded, failed가 있습니다. 각 상태가 곧 최종 사용자 연결 성공을 뜻하지는 않습니다. 검사 중인 쌍이 아직 대기 중인지, 검사 요청이 시작됐는지, 성공 응답을 받았는지 시간순으로 비교합니다. requestsSent, responsesReceived, currentRoundTripTime, state 같은 값은 구현에 따라 빠져 있을 수 있으므로 없는 값을 0으로 해석하지 않습니다.
성공한 쌍이 없다면 로컬·원격 후보 통계의 ID 연결을 따라 유형과 주소 노출 범위, 프로토콜을 확인합니다. 호스트 후보만 있고 외부 연결이 실패한다고 해서 모든 네트워크에서 같은 원인이라고 볼 수 없습니다. STUN 반사 주소 후보가 있는지, relay 후보가 생성됐는지 비교하면 추가 실험 방향을 좁힐 수 있지만, relay 후보가 없다는 것만으로 TURN 장애를 증명하지는 않습니다. TURN 자격증명, 할당 결과, 서버 로그는 앱과 서버 운영자가 따로 확인해야 합니다.
선택 경로가 생긴 뒤에도 실제 통신을 별도로 확인한다
선택된 후보 쌍은 현재 연결에 사용되는 경로에 대한 가장 직접적인 통계 단서입니다. stats report에서 transport와 candidate-pair의 참조 ID를 연결하고, nominated, bytesSent, bytesReceived, 응답 횟수와 타임스탬프 변화를 함께 봅니다. selected 같은 일부 필드는 구현별 차이가 있으므로 단일 필드 이름만 전 브라우저 기준으로 하드코딩하지 않습니다. 선택된 쌍이 나타났어도 앱 데이터가 전달되지 않으면 데이터 채널 상태, signaling 후속 동작, 원격 애플리케이션 처리를 분리해 점검합니다.
문제가 통화 도중 생겼다면 처음 성공한 쌍만 저장하지 말고 ICE restart 전후의 시간선도 비교합니다. 후보 쌍과 통계 객체는 경로 전환이나 재시작으로 바뀔 수 있습니다. 브라우저·버전별 통계를 반복 수집하고, 성공률을 표본 수와 함께 보고하면 간헐 실패를 단일 재현 사례와 구분할 수 있습니다. 이 절차는 원인 후보를 좁히는 진단 틀이지, NAT 유형이나 특정 네트워크 장비의 고장을 로그 하나로 증명하는 방법은 아닙니다.
전문가 관점: 진단 로그는 연결의 증거와 한계를 함께 남긴다
W3C WebRTC 통계 Editors’ Draft(Recommendation 채택 전 제안 초안)는 통계 객체를 특정 시점의 snapshot으로 설명하며, 구현되지 않았거나 적용되지 않는 항목은 결과에서 빠질 수 있다고 설명합니다. WebRTC 프로젝트의 버그 안내도 재현 단계, 브라우저·운영체제 버전, ICE 로그와 연결 통계를 함께 수집하도록 권합니다. 따라서 관측되지 않은 값은 “0”이나 “실패”로 바꾸지 말고 미제공으로 기록합니다. 후보 주소 등 네트워크 식별 정보가 들어갈 수 있으므로 덤프 공유 권한을 제한하고 필요한 항목만 남깁니다.