Эти кандидаты содержат информацию о сетевом соединении и их будет много для каждого клиента.

В процессе обмена ими система подберет самые подходящие 2 по одному из набора каждой из сторон.

Система начинает автоматически их генерировать в момент установки всех SDP (setRemoteDescription и setLocalDescription) и делает это в событии icecandidate на которое можно подписать функцию.

Как они выглядят

start page

Как видим они содержат реальный 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);
            },
        });
    }
start page
Потратить 2 кредита и начать обучение! У вас кредитов(а)
Задать вопрос, прокомментировать.