Signatur
Beschreibung
getLocalCandidates() liefert alle lokalen ICE-Kandidaten, die der ICE-Agent für genau diesen RTCIceTransport bisher gesammelt hat. Das sind z. B. Host-Kandidaten (lokale IP-Adressen bzw. mDNS-Namen), Server-reflexive Kandidaten (über STUN ermittelte öffentliche Adresse) und Relay-Kandidaten (über TURN).
Die Methode ist vor allem für Diagnose und Debugging gedacht: Man sieht, welche Netzwerkpfade die eigene Seite anbietet, ob STUN/TURN-Server erreichbar sind und ob überhaupt Relay-Kandidaten erzeugt wurden. Das ist hilfreich, wenn Verbindungen hinter restriktiven Firewalls oder symmetrischem NAT scheitern.
An den RTCIceTransport gelangt man über RTCDtlsTransport.iceTransport, also z. B. über sender.transport.iceTransport eines RTCRtpSender oder über RTCSctpTransport.transport.iceTransport für Datenkanäle. Die Transport-Objekte existieren erst, nachdem die lokale Beschreibung gesetzt wurde (setLocalDescription()).
Die zurückgegebene Liste ist eine Momentaufnahme: Kandidaten, die später gesammelt werden (Ereignis icecandidate bzw. gatheringstatechange), tauchen erst bei einem erneuten Aufruf auf. Nach einem ICE-Neustart enthält sie nur die Kandidaten der neuen Sitzung.
Rückgabewert
RTCIceCandidate-Objekten, eines je lokal gesammeltem Kandidaten der aktuellen ICE-Sitzung. Leer, wenn noch keine Kandidaten gesammelt wurden.Beispiele
Lokale Kandidaten eines Senders auslesen (mit Feature-Erkennung)
const pc = new RTCPeerConnection({
iceServers: [{ urls: 'stun:stun.l.google.com:19302' }]
});
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
stream.getTracks().forEach((track) => pc.addTrack(track, stream));
await pc.setLocalDescription(await pc.createOffer());
const iceTransport = pc.getSenders()[0].transport?.iceTransport;
if (iceTransport && typeof iceTransport.getLocalCandidates === 'function') {
const candidates = iceTransport.getLocalCandidates();
candidates.forEach((c) => console.log(c.type, c.protocol, c.address, c.port));
} else {
console.log('getLocalCandidates() wird nicht unterstützt');
}
Nach Abschluss des Sammelns prüfen, ob TURN funktioniert
const checkRelay = (iceTransport) => new Promise((resolve) => {
const evaluate = () => {
const hasRelay = iceTransport
.getLocalCandidates()
.some((c) => c.type === 'relay');
resolve(hasRelay);
};
if (iceTransport.gatheringState === 'complete') {
evaluate();
} else {
iceTransport.addEventListener('gatheringstatechange', () => {
if (iceTransport.gatheringState === 'complete') evaluate();
});
}
});
// Nutzung:
// const ok = await checkRelay(pc.getSenders()[0].transport.iceTransport);
// console.log(ok ? 'TURN erreichbar' : 'Kein Relay-Kandidat – TURN prüfen!');
Browserübergreifender Fallback über getStats()
const getLocalCandidatesCompat = async (pc) => {
const stats = await pc.getStats();
const result = [];
stats.forEach((report) => {
if (report.type === 'local-candidate') {
result.push({
type: report.candidateType,
protocol: report.protocol,
address: report.address,
port: report.port
});
}
});
return result;
};
const list = await getLocalCandidatesCompat(pc);
console.table(list);
// Wichtig · Fallstricke
- Browser-Kompatibilität: Die Methode steht zwar in der WebRTC-Spezifikation, ist aber in den großen Browsern (Chrome, Firefox, Safari) praktisch nicht implementiert. Immer per
typeof iceTransport.getLocalCandidates === 'function'prüfen und als FallbackRTCPeerConnection.getStats()mit Berichten vom Typlocal-candidateverwenden. RTCDtlsTransportbzw.sender.transportist vorsetLocalDescription()null– optionale Verkettung (?.) nutzen.- Bei Bundling (
bundlePolicy: 'max-bundle', Standard in modernen Browsern) teilen sich alle Sender und Empfänger einen Transport; die Kandidaten sind dann für alle identisch. - Datenschutz: Host-Kandidaten werden in modernen Browsern meist als mDNS-Namen (
…local) statt echter IP-Adressen ausgegeben, um IP-Leaks zu verhindern. Kandidatenlisten nicht ungefiltert an Dritte oder in Logs übermitteln. - Die Liste ist eine Momentaufnahme; für vollständige Ergebnisse auf
gatheringState === 'complete'warten.