即使我们确切地知道连接的路由,缓存 ICE 候选者和 sdp 是否也不起作用?

Win*_*hen 3 javascript ice stun webrtc turn

我知道在 P2P 和更动态的环境中缓存 ICE 候选者和 sdp 并不是一个好的做法,因为你缓存的东西可能无法申请下一个 WebRTC 连接。但是,在我们确切知道连接路线应该如何的情况下呢?

更具体,

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

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

jib*_*jib 6

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

比较两个不同RTCPeerConnection对象的createOffer()结果,您会发现它们不同。除了指纹之外,它们还包含本地RTCPeerConnection决定通过哪些端口发送/接收各个媒体,这些端口可能会有所不同。

要使用早期的缓存版本,您不仅需要告诉远程RTCPeerConnection对象要使用哪些端口,还需要告诉本地端口。这显然行不通:

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];
Run Code Online (Sandbox Code Playgroud)

在最新的 Chrome 中,会产生:

InvalidModificationError: The SDP does not match the previously generated SDP for this type
Run Code Online (Sandbox Code Playgroud)

...这是正确的,因为最新的 WebRTC 规范禁止在createOffersetLocalDescription之间进行 SDP 修改。

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

即使使用 TURN 服务器,也无法避免指纹不匹配的情况。