【发布时间】:2020-05-26 11:04:02
【问题描述】:
我已经成功地将 WebRTC 连接的提议、答案和候选冰从 A 传递到 B。此时,连接卡在 "connecting" 状态。启动器(A)似乎超时或一段时间后切换到"failed"状态,而其远程(B)永久保持在"connecting"状态。
任何帮助将不胜感激。
创建对等点(A 和 B):
let peer = new RTCPeerConnection({
iceServers: [
{
urls: [
"stun:stun1.l.google.com:19302",
"stun:stun2.l.google.com:19302",
],
},
{
urls: [
"stun:global.stun.twilio.com:3478?transport=udp",
],
},
],
iceCandidatePoolSize: 10,
});
创建报价 (A):
peer.onnegotiationneeded = async () => {
offer = await peer.createOffer();
await peer.setLocalDescription(offer);
};
收集冰候选人(A):
peer.onicecandidate = (evt) => {
if (evt.candidate) {
iceCandidates.push(evt.candidate);
} else {
// send offer and iceCandidates to B through signaling server
// this part is working perfectly
}
};
创建答案并填充候选冰 (B):
await peer.setRemoteDescription(offer);
let answer = await this._peer.createAnswer();
await peer.setLocalDescription(answer);
// send answer back to A through signaling server
for (let candidate of sigData.iceCandidates) {
await peer.addIceCandidate(candidate);
}
通过信令服务器 (A) 从 B 应答:
await peer.setRemoteDescription(answer);
检测连接状态变化(A和B):
peer.onconnectionstatechange = () => {
console.log("state changed")
console.log(peer.connectionState);
}
另请注意,有两次成功连接,但我还没有看到它再次工作。
编辑:我忘了说我也在创建一个数据通道(没有这个onicecandidate 事件似乎不会调用)。在构造 RTCPeerConnection 并附加任何事件处理程序后立即调用它。
let channel = peer.createDataChannel("...", {
id: ...,
ordered: true,
});
编辑 2:正如@jib 建议的那样,我现在也在 B 收集候选冰并将它们送回 A 进行添加。但是,完全相同的问题仍然存在。
编辑 3:似乎在我第一次硬重新加载 A 的网页和 B 的网页时连接。连接停止工作,直到我再次硬重新加载。有谁知道为什么会这样?至少我应该能够暂时继续开发,直到我弄清楚这个问题。
编辑 4:我删除了我正在使用的 iceServers 并将 RTCPeerConnection 构造函数留空。不知何故,它现在更可靠了。但我还没有在 iOS Safari 上成功连接!
【问题讨论】:
-
你只是在一方面收集 ICE 候选人。此外,您正在缓存它们,这违背了 Trickle ICE 的全部目的。相反,尽快向他们发出信号。一般来说,您希望 A 和 B 具有相同的代码,而不是不同的代码。
-
@jib 谢谢,我会尝试进行这些更改。没想到你也要把另一边的寒冰候选人召集起来。我暂时不太担心缓存候选冰的延迟,只是想先让它工作:) 编辑:无论如何,所有候选冰似乎都是同时通过的,所以缓存它们不会似乎没什么区别。
-
@jib 我已经尝试在 B 中收集 ice 候选人并将他们发送回 A,然后 A 调用
addIceCandidate,但仍然没有运气。
标签: javascript webrtc