具有完美协商的WebRTC-在mobile Safari上回滚不起作用

具有完美协商的WebRTC-在mobile Safari上回滚不起作用,webrtc,mobile-safari,rtcpeerconnection,Webrtc,Mobile Safari,Rtcpeerconnection,我正在考虑以下页面中的示例,尝试为我的小型视频会议应用程序实现完美的WebRTC协商: 不幸的是,我没有设法使它完全工作,尤其是mobile safari似乎以自己的方式处理回滚行为,下面是处理回滚行为的代码: if (description) { const offerCollision = description.type == 'offer' && (makingOffer || pc.signalingState != 'stable');

我正在考虑以下页面中的示例,尝试为我的小型视频会议应用程序实现完美的WebRTC协商:

不幸的是,我没有设法使它完全工作,尤其是mobile safari似乎以自己的方式处理回滚行为,下面是处理回滚行为的代码:

      if (description) {
        const offerCollision = description.type == 'offer' && (makingOffer || pc.signalingState != 'stable');
        this.ignoreOffer = !this.polite && offerCollision;
        if (this.ignoreOffer) {
          return;
        }
        if (offerCollision) {
          await Promise.all([pc.setRemoteDescription({ type: 'rollback' }), pc.setRemoteDescription(description)]);
因此,当在mobile safari上检测到要约冲突(
offerCollision===true
)并在我的代码中实现时调用
pc.setRemoteDescription({type:'rollback'})
,它会抛出类型为
InvalidStateError
的错误。仔细查看MDN()中有关此类错误的文档可以发现:

RTPeerConnection已关闭,或者处于与指定描述的类型不兼容的状态。例如,如果类型为rollback,且信令状态为stable、have local pranswer或have remote pranswer,则会引发此异常,因为您无法回滚已完全建立或处于连接最后阶段的连接。”

在回滚之前检查对等连接信令状态表明它处于“have local offer”状态,这应该是正常的,因为MDN表示在稳定、有本地pranswer或有远程pranswer的状态下不可能回滚(throws
InvalidStateError

在另一种情况下,当我的桌面Chrome浏览器在服务冲突中运行时,在回滚启动之前,所有内容都会以相同的信号状态正常工作

这里是否有人知道移动Safari的潜在错误或不同处理方式。

如中所述,Safari(iOS/mobile和macOS)有一个带
{type:'rollback}
。它还不支持规范中最新的完美协商建议
setLocalDescription
/
setRemoteDescription
中的可选描述

可以通过丢弃冲突的对等连接并重试()来修复此问题。为此,请在设置远程描述时使用以下步骤处理此错误:

  • 重置任何状态变量(例如,
    makingOffer
    isSettingRemoteAnswerPending
  • 通过调用
    peerConnection.Close()
  • 拆除任何对等连接事件侦听器(例如,
    negotiationneeded
    icecandidate
    track
  • 向其他对等方发送信号,以执行相同操作,例如通过websocket消息传递
  • 在收到重新启动的信号后,另一方可以执行相同的步骤,并最终创建一个新的报价以再次启动谈判过程

  • 这一流程的一个例子可以在中看到。

    经过多次迭代才到达这里Hey@smitkpatel,感谢您的评论,但我在链接的github repo中找不到任何有关回滚bahavior的代码。请您详细说明一下您的确切意思,或者您的代码可以如何帮助我?下面是一个重现错误的演示(仅在mobile Safari上出现)谢谢!我坚持放弃旧连接并创建新连接。这需要拆除所有事件侦听器,创建新的对等连接(+事件处理程序),并向其他客户端发送信号以执行相同操作()。一旦另一个客户端收到要重新启动的消息,它就可以创建报价以再次开始谈判。您的代码对我来说很有希望。感谢您分享它!我将在我还有时间的时候尝试一下。我怀疑它会很快出现,但我不会忘记它(在自动应用程序部署上挂一点)。我还想指出,我喜欢您编写-->清晰命名的方式,并且明显遵循单一责任原则。请随意将此作为答案发布,以便我可以同时接受。