我知道在P2P和更动态的环境中,缓存ICE候选对象和sdp并不是一个好习惯,因为缓存的内容可能无法申请下一个WebRTC连接。但是在我们确切知道连接路线应该如何的情况下呢?
更具体地说,
在这种情况下,我们确切地知道对等方的IP,并且我们确切地知道TURN服务器的IP(假设它不会改变),那么可以缓存ICE候选对象(TURN)吗?和SDP或SDP的一部分只是为了绕过ICE候选者和SDP交换部分?
答案 0 :(得分:2)
不。优惠和答案不仅仅包含如何建立联系。它们包含此连接 instance 的唯一指纹,因为可以在相同的两个已知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];
在最新版的Chrome中,它会产生:
InvalidModificationError: The SDP does not match the previously generated SDP for this type
...这是正确的,因为最新的WebRTC规范禁止SDP在 createOffer 和 setLocalDescription 之间进行修改。
在Firefox中,协商实际上已经完成,但是没有媒体或数据通道事件触发。
即使使用TURN服务器,也无法避免指纹不匹配。