我有一个聊天应用程序,我想扩展它的语音和视频聊天功能。基本上已经完成了,但我似乎无法通过重新协商来解决问题。
我使用了关于“完美协商”的 Mozilla 文档,但它仍然陷入软锁状态,我似乎无法修复。 问题:
用户A发送重新协商报价
public async createSDP() {
await this.rtcPeerConnection.setLocalDescription();
const sdp = this.rtcPeerConnection.localDescription;
if (!sdp) return false;
return sdp;
}
public async readSDP(sdp: any) {
let ignoreOffer = false;
try {
const offerCollision =
sdp.type === "offer" &&
(this.makingOffer || this.rtcPeerConnection.signalingState !== "stable");
ignoreOffer = !this.polite && offerCollision;
if (ignoreOffer) {
return false;
}
await this.rtcPeerConnection.setRemoteDescription(sdp);
return true;
} catch (err) {
console.error(err);
}
return false;
}
如果
ignoreOffer
是
true
,我尝试添加迭代,尝试 3 次,并逐渐增加延迟来处理将被删除的报价。我希望它能正确读取并发出答案,但收到“m 行顺序无效”的错误我尝试在发送重新协商报价后添加超时,以检查大约 20 秒后signalingState 是否仍处于“have-local-offer”状态,得到相同的“m-lines 顺序无效”错误。
我认为你可以避免这种情况。
我的猜测是,在您当前的代码中,用户 B:
收到报价并创建
rtcPeerConnection
setRemoteDescription
createAnswer
、通过网络发送将来自 getUserMedia
negotiationneeded
事件的连接
negotiationneeded
不会触发,也不会发生碰撞。所以正确的顺序是:
接收报价并创建rtcPeerConnection
getUserMedia
setRemoteDescription
createAnswer
,通过网络发送
否则,您可以让对等点 A 在添加来自对等点 B 的新报价之前完成处理答案。如果您直接删除它,则不会有来自 B 的视频/音频,因为媒体从未协商过。