결론 먼저 — 5축 체크리스트
| 축 | 본다 | 도구 |
|---|---|---|
| 1. ICE 상태 | iceConnectionState 천이 로그 | chrome://webrtc-internals |
| 2. 네트워크 품질 | RTT, jitter, packet loss | getStats() |
| 3. 디바이스 | 마이크/스피커 권한, 샘플레이트 | navigator.mediaDevices |
| 4. 시그널링 | WebSocket 살아있는지 | DevTools Network |
| 5. SDP | codec 합의, m-line 순서 | SDP 비교 |
“끊긴다”는 신호는 5축 중 하나다. 코드부터 보지 말고, 5축의 어느 칸이 빨간색인지부터 짚는다.
축 1 — ICE 상태
가장 먼저 보는 건 RTCPeerConnection의 iceConnectionState 천이 로그.
new → checking → connected → completed: 정상new → checking → failed: 단계 4 (NAT/방화벽)connected → disconnected → failed: 도중에 네트워크 변동
chrome://webrtc-internals에서 “Stats Tables” 안에 그래프로 그려진다. 시간 축이 일치하므로 “어느 시점에 끊겼는지” 한눈에 보인다.
축 2 — 네트워크 품질 (RTT, jitter, packet loss)
ICE는 connected인데 음성이 깨진다면 네트워크 품질을 의심한다.
inbound-rtp.jitter: 50ms 이상이면 인지되는 떨림inbound-rtp.packetsLost / packetsReceived: 1% 이상이면 음성 끊김 체감candidate-pair.currentRoundTripTime: 200ms 이상이면 turn-taking 부자연
이 값들을 1초 단위로 로깅해 두면, “여기서 끊겼다”고 느낀 시점과 데이터 매칭이 쉬워진다.
축 3 — 디바이스 (마이크 / 스피커)
- 마이크 권한 거부 / 다른 앱이 점유 중
- 샘플레이트 미스매치 (브라우저 기본 48kHz vs 일부 기기 16kHz)
- AGC / AEC가 너무 적극적이라 음성 일부가 잘림
navigator.mediaDevices.enumerateDevices()로 디바이스 리스트를 출력하고, getUserMedia 결과 트랙의 sampleRate / channelCount를 확인한다.
축 4 — 시그널링 채널
WebSocket 또는 HTTP long-poll이 살아있는지 점검.
- 토큰 만료로 끊겨 있으면 reconnect 로직이 도는 동안 통화가 비정상 상태
- DevTools Network 탭의 ws 연결 Frames에서 last ping/pong 시간 확인
- 한쪽이 끊긴 줄 모른 채 SDP/ICE 메시지를 보내고 있을 수 있음
축 5 — SDP 협상
connected였지만 검정 화면 / 무음이라면 SDP 협상을 의심한다.
- 양쪽 SDP의
m-line순서가 동일한가 a=rtpmap의 codec이 합의됐는가- 한쪽만 H.264, 다른 쪽만 VP8 같은 mismatch 여부
chrome://webrtc-internals에서 양쪽 SDP를 그대로 비교 가능하다.
5축 체크리스트의 가치 — “어디 봐야 하나”가 자동화되는 것
처음 데모를 디버깅할 때는 코드부터 들여다봤다. 그런데 코드를 한참 본 끝에 결국 ICE에서 멈춰 있었다는 결론이 나오면, 그 사이의 시간이 모두 낭비였다.
5축 체크리스트는 이 순서를 강제한다. 코드를 보기 전에 5축 중 어느 칸이 빨간색인지부터 가른다. 그러면 들여다볼 코드 범위가 자연스럽게 좁아지고, 디버깅 사이클이 짧아진다.
개인 메모 — chrome://webrtc-internals를 늦게 알았다
WebRTC 데모를 만들기 시작하고 한참이 지나서야 chrome://webrtc-internals의 존재를 알았다. 그 전까지는 console.log로 stat 값을 직접 찍어가며 디버깅했고, 시간 축이 일치하는 그래프가 없으니 “언제 끊겼는지”를 짚는 데도 한참 걸렸다.
이 페이지를 알게 된 뒤로 디버깅이 다른 종류의 작업이 됐다. “코드를 짚어 가설 → 검증” 순서가 아니라 “그래프 → 가설 → 코드 점검” 순서로 흘러간다. 도구의 존재를 모르고 들이는 시간이 도구를 알고 줄일 수 있는 시간보다 훨씬 길었던 셈이다.
답글 남기기