处理使用PeerConnection时处理ICE候选者的过程?

时间:2015-04-15 15:59:46

标签: javascript google-chrome firefox webrtc p2p

我已经用尽所有可能使稳定的WebRTC实施工作,并希望得到一些建议。

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

  • 在Chrome浏览器上发送SDP之前等待所有候选人收集
  • 收集候选人后立即发送候选人,并在设置本地sdp后将其添加到远程连接
  • 一旦设置了本地和远程描述(远程和本地),就添加候选者
  • 收到候选人并在回复后发回候选人
  • 在冰故障时重置对等连接
  • 其他人(匆忙)

基本上我要求某人帮忙解决一下图表或逐步处理ice应该处理的过程,以便为chrome和firefox跨浏览器提供可行的解决方案(两者都是最新的当前发布时间)。

此时我已经因为没有其他任何可能性而烦恼,我们将非常感谢任何帮助。

谢谢, 十二月:)

2 个答案:

答案 0 :(得分:7)

我同情你的挫败感。

对于RTCPeerConnection,在调用createOffer()然后调用setLocalDescription()之后,ICE代理将开始收集ICE候选。此时,您可以决定是否使用Trickle ICE,候选人一旦被提供就被发送到远程对等体,或者您可以等待所有候选人被收集(大多数教程我和#39;我遇到似乎采取了涓涓细流的方法,但错过了正确处理这个问题的一些细节)。

涓涓细流:

当触发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的评论)。

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

答案 1 :(得分: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))