마지막 업데이트 2026-07-22
useWebRTC는 V1(레거시)의 P2P 1:1 연결을 캡슐화하는 기반 훅. offer/answer SDP 교환, ICE candidate buffering, 다층 복구(ICE restart → full reconnect → retry)를 담당한다. V2(SFU)는 이 훅 대신 mediasoup(#10)을 쓴다.
"session-audio"(릴레이 #6), "host-audio"(게스트↔호스트 미디어), "screen-share"(화면 공유) 세 갈래로 인스턴스화한다. 한 페이지에 여러 P2P가 공존하므로 모든 시그널링 이벤트가 connectionId로 필터링된다.
소켓 이벤트는 역할 접두사를 쓴다: 자신은 ${role}-sdp-offer/answer/ice-candidate를 emit하고, 상대(oppositeRole)의 같은 이벤트를 listen한다. 모든 핸들러는 connectionId !== props.connectionId면 무시.
if (peerConnection.current.remoteDescription) { await peerConnection.current.addIceCandidate(parsed); // 준비됨 → 즉시 추가 } else { candidateQueue.current.push(parsed); // 아직 remote SDP 없음 → 큐잉 }
setRemoteDescription 직후(handleOffer/handleAnswer)에 일괄 flush한다.연결 끊김에 대해 비용이 낮은 것부터 단계적으로 대응한다.
attemptIceRestart L76): 기존 PeerConnection 재사용. createOffer({iceRestart:true}) → setLocalDescription → offer 재전송. 가드: PC가 closed거나 signalingState !== "stable"(협상 진행 중)이면 skip. iceState disconnected 시 1차 시도.startDisconnectedTimeout L126): 일정 시간 disconnected 지속 시 onFailed() 호출(상위가 세션 종료/재시작 결정).attemptFullReconnection): ICE failed 시 즉시 전체 재연결(PC 폐기 후 재생성). ICE restart로 회복 안 되는 경우.enableRetry면 connect 실패/실패 콜백 시 onRetryAttempt(attempt, max)와 함께 재시도, 소진 시 onRetryFailed.connected/completed로 복귀하면 카운터·타이머 리셋.onnegotiationneeded: 양측 모두 재협상 가능(트랙 add/replace 시). signalingState==="stable"+비협상 중일 때만 새 offer.useWebRTCMonitoring으로 getStats 통계를 소켓 송출(#19).| 반환 | 역할 |
|---|---|
connect() | PC 생성·offer 시작(initiator) |
disconnect() | PC close·리스너 해제·큐 정리 |
addTrack(track, stream) | 송신 트랙 추가(릴레이 AI 음성 등 → onnegotiationneeded 유발) |
isConnected() | 연결 상태 조회 |
콜백: onTrackReceived(수신 트랙), onAnswered, onDisconnected, onFailed, onError, onRetryAttempt/Failed.
| 사용처 | connectionId |
|---|---|
| 세션 릴레이(#6, guest/host) | session-audio |
| 게스트/호스트 미디어 매니저 | host-audio |
| 화면 공유 | screen-share |
iceRestartAttemptCount, isRetrying)로 가드. 임의 수정 시 재연결 폭주.| 파일/심볼 | 역할 |
|---|---|
| use-web-rtc.ts | P2P 연결·시그널링·복구 본체(969L) |
| handleOffer/Answer/Candidate (L268–367) | SDP·candidate 처리 |
| attemptIceRestart (L76) / startDisconnectedTimeout (L126) | 복구 1·2단계 |
| use-guest-media-manager.ts / use-host-media-manager.ts | V1 미디어 매니저(이 훅 래핑) |
| use-screen-share.ts | 화면 공유(이 훅 사용) |