是否可以将 WebRTC SDP 报价转换为答案?

Is it possible to convert a WebRTC SDP offer to answer?

我有两个想要通过 WebRTC 相互连接的对等方。通常,第一个对等点会创建一个报价并通过信令 channel/server 将其发送给第二个对等点,第二个对等点会回应一个答案。这个场景工作正常。

但是,是否可以支持两个对等点碰巧尝试同时相互连接的情况,两个对等点都通过信令服务器同时向彼此发送 SDP 提议。

// Both peers do this simultaneously:
const conn = new RTCPeerConnection(null);
const sdpOffer = await conn.createOffer();
await conn.setLocalDescription(sdpOffer);
signalingService.send(peerId, sdpOffer);

// At some point in the future both peers also receive an SDP offer 
// (rather than answer) from the other peer whom they sent an offer to 
// via the signaling service. If this was an answer we'd call 
// RTCPeerConnection.setRemoteDescription, however this doesn't work for an 
// offer: 

conn.setRemoteDescription(peerSDPOffer); 
// In Chrome results in "DOMException: Failed to execute 'setRemoteDescription' on 'RTCPeerConnection': Failed to set remote offer sdp: Called in wrong state: kHaveLocalOffer"

我什至试图通过将 SDP 类型从 offer 重写为 answer 以及将 setup:actpass 重写为 setup:active 来 "convert" 收到的对等方提供的答案,但是这似乎不起作用,相反我只是得到一个新的异常。

所以问题是,这个同时 connect/offer 用例是否以某种方式得到支持 - 或者我应该关闭一个 side/peer RTCPeerConnection 并这次使用 RTCPeerConnection.createAnswer 实例化一个新的?

这种情况被称为"signaling glare"。 WebRTC API 并没有真正定义如何处理这个(除了一些叫做 "rollback" 但它还没有在任何浏览器中实现并且到目前为止没有人错过它)所以你必须自己避免这种情况.

简单地替换 a=setup 是行不通的,因为底层 DTLS 机制仍然需要客户端和服务器的概念。

最近如何避免眩光的答案是使用完美协商模式:https://developer.mozilla.org/en-US/docs/Web/API/WebRTC_API/Perfect_negotiation

但是,OP 所描述的内容确实可以通过对一个对等方的设置 setup:active 和另一个对等方 setup:passive 的设置进行轻微修改来工作: https://codepen.io/evan-brass/pen/mdpgWGG?editors=0010

它可能不适用于音频/视频连接(因为它们可能需要协商编解码器),但我已经在 Chrome/Firefox/Safari 上针对仅 DataChannel 连接进行了测试。

您可以选择哪个对等方是主动的,哪个是被动的,使用您使用的任何系统来确定 'politeness' 在完美协商中。一种可能性是比较 DTLS 指纹并使较大的指纹成为活动对等方。