是否可以将 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 指纹并使较大的指纹成为活动对等方。
我有两个想要通过 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 指纹并使较大的指纹成为活动对等方。