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

Posted

技术标签:

【中文标题】是否可以将 WebRTC SDP 报价转换为答案?【英文标题】:Is it possible to convert a WebRTC SDP offer to answer? 【发布时间】:2019-05-28 04:38:19 【问题描述】:

我有两个想要通过 WebRTC 相互连接的对等方。通常,第一个对等点会创建一个提议并通过信令通道/服务器将其发送给第二个对等点,第二个对等点会以答案进行响应。此方案运行良好。

但是,是否有可能支持两个对等方碰巧同时尝试相互连接的情况,两者都通过信令服务器同时向彼此发送 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 重写为 answersetup:actpasssetup:active 来将收到的同行提议“转换”为答案,但这似乎不起作用,相反我只是得到一个新的例外。

所以问题是,这种同时连接/提供用例是否以某种方式支持 - 还是我应该关闭一侧/对等 RTCPeerConnection 并使用 RTCPeerConnection.createAnswer 实例化一个新的?

【问题讨论】:

我的信令服务器本质上为每个对等点分配了一个会话 ID;我避免这种双重报价的简单策略是具有较高 id 的对等方开始报价。你需要这样的某种协调。 谢谢@deceze - 这正是我要做的事情 【参考方案1】:

这种情况称为“信号眩光”。 WebRTC API 并没有真正定义如何处理这个问题(除了所谓的“回滚”,但它还没有在任何浏览器中实现,到目前为止没有人错过它)所以你必须自己避免这种情况。

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

【讨论】:

Firefox 实现了“回滚”FWIW。它并没有根据规范触发它应该触发的所有事件,但在这种简单的情况下,它应该可以很好地回滚对等连接之一的初始提议。 在一个固有的 P2P 系统中拥有“客户端”和“服务器”的核心基础是很有趣的 LOL 对于那些来这里寻找防眩光/完美协商解决方案的人:下一个 Chrome 版本 (M80) 也将处理回滚(当时可在 Chrome Canary 中测试)。最新的 webrtc-spec 进行了一些更改以避免竞争情况,还包括一个示例,请参阅:w3.org/TR/webrtc/#perfect-negotiation-example

以上是关于是否可以将 WebRTC SDP 报价转换为答案?的主要内容,如果未能解决你的问题,请参考以下文章

WebRTC:将视频添加到 SDP 中没有 BUNDLE 行的音频呼叫

如何使用 ice-candidates 处理 sdp 报价并生成合适的响应

WebRTC:对多个对等连接使用相同的 SDP?

Firefox 中的 WebRTC 直播流(H264)错误,无法生成有效的 SDP 答案

如何设置 WebRTC 数据通道最大比特率?

WebRTC:在 Firefox 中使用 VP9 编码的 SDP