React+Firebase项目中WebRTC ICE候选者监听器未触发问题排查
监听器绑定时机滞后
你的代码中,peerConnection.onicecandidate是在创建offer、上传offer到Firebase之后才绑定的。但ICE候选收集在调用createOffer或setLocalDescription后就已经启动,这会导致你错过早期甚至全部的ICE候选事件。正确的做法是在创建RTCPeerConnection实例后立即绑定监听器,可调整逻辑如下:const peerConnection = new RTCPeerConnection(configuration); // 先声明候选集合变量,后续赋值 let candidatesCollection; // 提前绑定ICE候选监听器 peerConnection.addEventListener('icecandidate', async (e) => { if (e.candidate && candidatesCollection) { console.log("Adding caller ICE candidates"); await addDoc(candidatesCollection, e.candidate.toJSON()); } }); // 再执行添加轨道、创建offer等操作 localStream.getTracks().forEach((track) => { console.log("Caller adding localstream tracks to PC", track); peerConnection.addTrack(track, localStream); }); // 创建roomRef后赋值候选集合 const roomRef = await addDoc(roomsCollectionRef, roomWithOffer); candidatesCollection = collection(roomRef, "callerCandidates");媒体轨道添加异常
检查localStream是否成功获取有效轨道:确认navigator.mediaDevices.getUserMedia返回的流包含视频和音频轨道,控制台是否输出"Caller adding localstream tracks to PC"且track对象正常。如果轨道未正确添加到peerConnection,ICE收集流程可能不会被触发。ICE候选池配置的影响
你设置了iceCandidatePoolSize:10,该配置会让浏览器提前预收集ICE候选。如果在绑定监听器之前预收集已完成,后续就不会触发icecandidate事件,调整监听器绑定时机可解决此问题。事件处理函数的异步阻塞
监听器中使用await addDoc,若Firebase写入操作延迟或失败,可能阻塞后续候选的处理。建议添加错误捕获并避免阻塞事件循环:peerConnection.onicecandidate = (e) => { if (e.candidate) { console.log("Adding caller ICE candidates"); // 使用void避免阻塞,添加错误捕获 void addDoc(candidatesCollection, e.candidate.toJSON()).catch(err => { console.error("Failed to add ICE candidate:", err); }); } };STUN服务器不可达
虽然你使用了谷歌公共STUN服务器,但部分网络环境下可能无法访问。可通过浏览器的chrome://webrtc-internals/页面查看WebRTC日志,确认STUN服务器是否能正常连接、是否成功获取服务器反射地址。
内容的提问来源于stack exchange,提问作者Dagem

