我一直在尝试实现WebRTC的“完美协商”,如this blog post中所述。不幸的是,我经常在对话中礼貌地触发错误(在下面的链接代码中,这是最后一个加入的对等体)。
[两个最常见的错误是由InvalidStateError: Cannot rollback local description in stable
引起的this line和由ONN DOMException: "Cannot set local offer in state have-remote-offer"
触发的here引起的。第二个错误对我来说是莫名其妙的,因为前一行检查我们应该处于this line状态,并且这是之后的第一个异步调用。
[如果您想自己尝试,我的代码是stable
。它可以直接部署在Heroku上:
hosted on GitHub
或可以通过更改server.js的第1、7-10和15行使用自签名证书在本地进行测试。
我在使用台式机Firefox(版本76、73,台式机Chromium 80和它们在Android上的最新移动版本)进行测试时遇到了这些问题。任何帮助,将不胜感激。而且,我也希望能够在我无法亲自测试的iPad(Safari> = 11)上可靠地工作。
TL; DR: Firefox 77和heroku create
git push heroku master
中的浏览器错误fixed,以及Chrome中的the spec。
separate bug ...第二个错误对我来说是莫名其妙的,因为前一行检查了我们应该处于稳定状态,并且这是之后的第一个异步调用。
WebRTC协商代码的任务很棘手,即将同步信令消息转换为RTCPeerConnection对象上的异步操作。为了确保顺序,这些异步方法在内部为ONN DOMException: "Cannot set local offer in state have-remote-offer"
,因此一次只能运行一个,因为状态机。
在发出信号压力的情况下,内部链可能会填满,这使事情变得复杂,因为您调用的方法最终运行得较晚,而不是立即处于刚同步观察的状态。
发生“第二个错误”是因为当RTCPeerConnection对象的内部chained为非空时,浏览器错误地触发了negotiationneeded
事件。规格现在为operations chain,因此不会发生。
由于浏览器控制何时触发fixed事件,因此将对此进行处理。
negotiationneeded
[不礼貌方面的“第一个错误”类似地是链过载的症状:同步状态检查我们不稳定,然后执行此操作:
InvalidStateError: Cannot rollback local description in stable
[我怀疑这时链上还有其他协商方法,这些方法使我们在运行
if (offerCollision) { // pc.signalingState != "stable" await Promise.all([ pc.setLocalDescription({ type: "rollback" }), pc.setRemoteDescription(description), ]); }
回滚之前回到“稳定”状态。
为了解决这个问题,规格添加了setLocalDescription
,因此您可以将上面的内容替换为:
implicit rollback这比较好用,因为是否需要回滚的决定是在链接的方法内部进行的,当时(可能稍后)查看正确的信令状态。
不幸的是,这种填充不那么容易。您可以尝试类似的操作:
await pc.setRemoteDescription(description); // implicit rollback only if needed
或等待浏览器实施隐式回滚。