在您调用 setLocalDescription(); 之前,PeerConnection 不会开始收集候选人;提供给 setLocalDescription 的信息告诉 PeerConnection 需要收集多少候选人。(setLocalDescription 的这种行为在https://datatracker.ietf.org/doc/html/draft-ietf-rtcweb-jsep-03#section-4.2.4的定义中有所说明)
以下是在同一浏览器窗口中的两个 PeerConnection 之间建立连接的完整流程(省略添加 MediaStream 以专注于信令):
var pc1, pc2, offer, answer;
pc1 = new webkitRTCPeerConnection(options);
pc2 = new webkitRTCPeerConnection(options);
pc1.onicecandidate = function(candidate) {
pc2.addIceCandidate(candidate);
};
pc2.onicecandidate = function(candidate) {
pc1.addIceCandidate(candidate);
};
pc1.createOffer(onOfferCreated, onError);
function onError(err) {
window.alert(err.message);
}
function onOfferCreated(description) {
offer = description;
pc1.setLocalDescription(offer, onPc1LocalDescriptionSet, onError);
}
function onPc1LocalDescriptionSet() {
// after this function returns, pc1 will start firing icecandidate events
pc2.setRemoteDescription(offer, onPc2RemoteDescriptionSet, onError);
}
function onPc2RemoteDescriptionSet() {
pc2.createAnswer(onAnswerCreated, onError);
}
function onAnswerCreated(description) {
answer = description;
pc2.setLocalDescription(answer, onPc2LocalDescriptionSet, onError);
}
function onPc2LocalDescriptionSet() {
// after this function returns, you'll start getting icecandidate events on pc2
pc1.setRemoteDescription(answer, onPc1RemoteDescriptionSet, onError);
}
function onPc1RemoteDescriptionSet() {
window.alert('Yay, we finished signaling offers and answers');
}
由于您在问题中包含了 mozPeerConnection,我会注意到 Firefox 目前不会生成“trickle Candidates”。这意味着它将在提议/答案中将其候选地址作为“c”行包含在内,并且永远不会调用 onicecandidate 回调。
这种方法的缺点是 Firefox 在创建它的提议/答案之前必须等待它的所有候选人被收集(这个过程可能涉及联系 STUN 和 TURN 服务器并等待响应或请求超时)。