代码之家  ›  专栏  ›  技术社区  ›  Winston Chen

即使我们确切知道连接的路径,缓存ICE候选和SDP是否也不会工作?

  •  1
  • Winston Chen  · 技术社区  · 6 年前

    我理解,在p2p和更动态的环境中,缓存候选ICE和SDP并不是一个好的实践,因为缓存的内容可能无法应用于下一个WebRTC连接。但是在我们确切知道连接路径应该是什么的情况下呢?

    更具体地说,

    1. 假设我们有1个turn服务器(没有负载平衡,因此没有内部路由)
    2. 以及2个具有固定IP的对等机,它们希望不时与WebRTC连接。

    在这种情况下,我们确切地知道对等端的IP是什么,并且我们确切地知道TURN服务器的IP是什么(假设它不会改变),缓存ICE候选(TURN)和SDP或SDP的某些部分是否可以,只是为了绕过ICE候选和SDP交换部分?

    1 回复  |  直到 6 年前
        1
  •  2
  •   jib    6 年前

    不,报价和答案不仅仅包含 怎样 连接。它们包含此连接的唯一指纹 实例 ,因为可以在同一个两个已知IP之间建立任意数量的安全连接,甚至可以同时建立。

    比较 创建程序() 两种不同的结果 rtc对等连接 对象,你会发现它们是不同的。除了指纹,它们还包含本地 rtc对等连接 已决定发送/接收个别媒体,可能会有所不同。

    要使用早期的缓存版本,您不仅需要告诉远程 rtc对等连接 对象要使用的端口,但也要使用本地端口。这显然不起作用:

    const [pc1, pc2, pc3] = [1,2,3].map(() => new RTCPeerConnection());
    
    (async () => {
      try {
        [pc1, pc2].forEach(pc => pc.createDataChannel("dummy"));
        pc3.ondatachannel = () => console.log("pc3 ondatachannel");
        await pc1.createOffer();
        await pc1.setLocalDescription(await pc2.createOffer()); // Uh oh! pc2 not pc1
        await pc3.setRemoteDescription(pc1.localDescription);
        await pc3.setLocalDescription(await pc3.createAnswer());
        await pc1.setRemoteDescription(pc3.localDescription);
      } catch (e) {
        console.log(e);
      }
    })();
    
    pc1.onicecandidate = e => pc3.addIceCandidate(e.candidate);
    pc3.onicecandidate = e => pc1.addIceCandidate(e.candidate);
    pc1.oniceconnectionstatechange = e => console.log(pc1.iceConnectionState);
    pc3.ontrack = e => video.srcObject = e.streams[0];

    在最新的Chrome中,这将产生:

    InvalidModificationError: The SDP does not match the previously generated SDP for this type
    

    …这是正确的,因为最新的WebRTC规范禁止SDP在 创造要约 设置本地描述 .

    在Firefox中,协商实际上已经完成,但没有触发媒体或数据通道事件。

    即使有了转弯服务器,指纹也不可能不匹配。