Эти кандидаты содержат информацию о сетевом соединении и их будет много для каждого клиента.
В процессе обмена ими система подберет самые подходящие 2 по одному из набора каждой из сторон.
Система начинает автоматически их генерировать в момент установки всех SDP (setRemoteDescription и setLocalDescription) и делает это в событии icecandidate на которое можно подписать функцию.
Как они выглядят
Как видим они содержат реальный IP адрес за пределами роутера в локальной сети (за NAT).
function onIceCandidate(e) {
console.log(e);
}
async function offer(e) {
const peerConnection = window.peerConnection = new RTCPeerConnection(null);
window.peerConnection.addEventListener('icecandidate', e => onIceCandidate(e));
...
function onIceCandidate(e) {
console.log(e);
let url = '{{server_name}}:{{server_port}}/ice';
$.ajax({
type: "POST",
url: url,
contentType: "application/json",
data: JSON.stringify({
'sid': window.sessionStorage.getItem('sid'),
'ice': JSON.stringify(e.candidate),
}),
success: (data) => {
console.log(data);
},
});
}