【问题标题】:Handling the process of handling ICE candidates when using a PeerConnection?使用 PeerConnection 时处理 ICE 候选的过程?
【发布时间】:2015-04-15 15:59:45
【问题描述】:

我已经用尽了所有可能来获得稳定的 WebRTC 实施,并希望获得一些建议。

已考虑处理跨浏览器工作连接的所有可能解决方案,例如:

  • 等到所有候选人都收集完毕后再在 Chrome 浏览器上发送 SDP
  • 收集候选人后立即发送他们,并在设置本地 sdp 后将他们添加到远程连接
  • 在设置本地和远程描述后添加候选对象(远程和本地)
  • 在收到候选人时添加报价候选人并将答案发回给候选人
  • ice 失败时重置对等连接
  • 其他(匆忙中)

基本上,我要求有人帮助提供图表或逐步处理冰的过程,以便为 chrome 和 firefox 跨浏览器提供有效的解决方案(两者都是最新的当前发布时间)。

在这一点上,我已经耗尽了对任何其他可能性的思考,如果能提供任何帮助,我将不胜感激。

谢谢, 十二月:)

【问题讨论】:

  • 没有看到所有代码,很难提供帮助。 O'Reilly 有一本免费的 WebRTC 电子书,其中包含可以帮助您了解流程的代码示例……it-ebooks.info/book/3287
  • @mtbikemike 我已经按照那本书中的流程/示例进行操作,但没有运气创建稳定的客户端 :(。但是我发现它是一本非常有趣/写得很好的书,谢谢 :)
  • 你找到一个好的策略了吗,问题是ice候选被发送,与远程对等点是否设置了它的remoteDescription无关。所以我唯一能想到的就是要么通过不设置本地描述来延迟用户A端的发送,要么将它们存储在用户B端的堆栈中,直到设置了remoteDescription。

标签: javascript google-chrome firefox webrtc p2p


【解决方案1】:

我很同情你的挫败感。

对于 RTCPeerConnection,调用 createOffer() 和 setLocalDescription() 后,ICE 代理将开始收集 ICE 候选者。此时你可以决定是否使用 Trickle ICE,候选者一可用就被发送到远程对等点,或者你可以等待所有候选者被收集(大部分教程我来cross 似乎采用了涓涓细流的方法,但错过了一些有关正确处理此问题的细节)。

涓流方法:

当触发 RTCPeerConnectionIceEvent 时有一个新的候选者可用:

peerConnection.onicecandidate = function(newRTCPeerConnectionIceEvent) {

    var newCandidate = newRTCPeerConnectionIceEvent.candidate;
    // send candidate to remote via signalling channel
}

在远端,候选人可以被添加到他们的对等连接中:

peerConnection.addIceCandidate(RTCIceCandidate);

如果您还没有在远程对等连接上调用 setRemoteDescription,我相信过早添加候选人会产生错误,因为这会在尚未设置时尝试将其添加到 remoteDescription。看到这个Errors when ICE Candidates are received before answer is sent

非涓流方法:

您可以等待所有候选人聚集如下:

peerConnection.onicecandidate = function(newRTCPeerConnectionIceEvent) {

    if (newRTCPeerConnectionIceEvent.candidate === null) {

       // send the offer (generated previously) to the remote peer
       // the offer sdp should contain all the gathered candidates
    }
}

有关此技术的更多讨论,请参阅此链接:http://muaz-khan.blogspot.co.uk/2015/01/disable-ice-trickling.html(请参阅页面底部关于在报价已包含所有候选人时生成答案 sdp 的评论)。

请注意,信令机制可能会影响您的方法,即您的信令中是否存在任何明显的延迟。我认为涓流方法假设您使用的是低延迟信令,因为它旨在减少呼叫建立时间。

【讨论】:

  • 我觉得这并不能回答问题,您如何以不会导致错误的涓流方式发送冰候选人。一旦你设置本地描述浏览器开始发送冰消息。并且由于在远程对等方有 sdp msg 和 ice msg 的不同处理程序,发生的情况是,即使在发送的 spd msg 被设置为远程之前,许多 ice 候选者已经到达并崩溃。所以是的,你是怎么处理的。从列出的策略 OP 中,我尝试了 #3 和堆栈实现(我将所有候选冰块放入堆栈,然后一旦设置了 remoteDescription,我就将它们全部添加)
【解决方案2】:

我发现这个功能在你的情况下很有用:)

function waitForAllICE(pc) {
  return new Promise((fufill, reject) => {
    pc.onicecandidate = (iceEvent) => {
      if (iceEvent.candidate === null) fufill()
    }
      setTimeout(() => reject("Waited a long time for ice candidates..."), 10000)
  }) 
} 

然后你可以做一些类似的事情

pc.createOffer()
  .then(offer => pc.setLocalDescription(offer))
  .then(  ()  => waitForAllICE(pc))
  .then(  ()  => signallingWire.send(pc.localDescription))
  .catch(  e  => smartErrorHandling(e))

【讨论】:

  • 我觉得这是一个 hack,但不知道等待空候选人如何表明是时候开始添加冰候选人了。
  • 我相信“空冰候选者表明所有已被发现”的行为在规范中。我不会那样写的,(显式比隐式好)但是你去吧。
  • 可以确认这在其他地方有解释
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-27
  • 1970-01-01
  • 2014-10-18
  • 1970-01-01
  • 1970-01-01
  • 2016-08-08
相关资源
最近更新 更多