为什么对方接收不到我的ICE候选?

皇甫俊凤 阅读 43

我在用WebRTC做点对点视频通话,设置了onicecandidate事件,但对方就是收不到我的候选信息,折腾了好久搞不懂哪里错了。

代码是这样的:

  
pc.onicecandidate = (event) => {  
  if (event.candidate) {  
    console.log("发送候选:", event.candidate); // 这里确实有输出  
    // 通过WebSocket发送给对方  
    ws.send(JSON.stringify({ type: "candidate", candidate: event.candidate }));  
  }  
};  

对方的调试日志显示只收到offer和answer,没有candidate类型的消息。检查过网络没问题,信令通道也没报错,发送日志里的candidate对象结构看起来也正常…

我来解答 赞 5 收藏
二维码
手机扫码查看
1 条解答
程序猿翌岍
WebRTC 的 ICE 候选传不到对方,从你贴的代码看,问题很可能出在你没有等待 onicegatheringstatechange 事件完成。

WebRTC 在生成 ICE 候选是异步的,而且会分批发送多个候选。你当前的代码只要一触发 onicecandidate 就立刻发送,但此时可能还没收集完所有候选,中间就被关闭或跳过了。

你需要加一个判断,等 iceGatheringState 变成 complete 后再发送。或者更稳妥的做法是:监听 onicegatheringstatechange,确保 ICE 收集完成后再发送整批候选。

一个简单修复方法如下:

pc.onicecandidate = (event) => {
if (event.candidate) {
console.log("发现候选:", event.candidate);
// 缓存起来,而不是直接发送
iceCandidatesQueue.push(event.candidate);
} else {
// candidate 为 null 表示收集完成
console.log("ICE收集完成,准备发送全部候选");
sendAllCandidates();
}
};

function sendAllCandidates() {
if (iceCandidatesQueue.length > 0) {
ws.send(JSON.stringify({
type: "candidates",
candidates: iceCandidatesQueue
}));
iceCandidatesQueue = [];
}
}


另外注意,有些浏览器会连续发多个 null 的 candidate,或者中途暂停再继续收集,所以你接收方也得处理这种情况,不能收到一次 null 就以为万事大吉。

如果你在 WP 里面做 WebRTC,别忘了有些插件可能会注入脚本,干扰 WebSocket 通信。最好先禁用插件,用裸站测试信令流程。
点赞 2
2026-02-03 23:16