Signatur
Beschreibung
Die schreibgeschützte Eigenschaft port eines RTCIceCandidateStats-Objekts enthält die Portnummer, die zum Kandidaten gehört. Solche Statistikobjekte erhält man aus dem RTCStatsReport, den RTCPeerConnection.getStats() liefert. Sie haben den type "local-candidate" oder "remote-candidate".
Zusammen mit address und protocol beschreibt port den Transportendpunkt eines Kandidaten vollständig. Welcher Port das ist, hängt vom candidateType ab:
- host: der lokale Port der Netzwerkschnittstelle,
- srflx: der Port, den der STUN-Server nach der NAT-Übersetzung sieht (öffentlicher Port),
- relay: der Port auf dem TURN-Server, der für diese Allokation vergeben wurde,
- prflx: ein Port, der während der Konnektivitätsprüfung ermittelt wurde.
Nützlich ist die Eigenschaft vor allem bei der Fehlersuche. Man kann damit prüfen, welches Kandidatenpaar tatsächlich gewählt wurde, ob Firewalls bestimmte Ports blockieren oder ob der Datenverkehr über einen TURN-Server läuft (z. B. Port 3478 oder 443).
Rückgabewert
undefined sein, wenn der Browser den Wert nicht liefert, z. B. aus Datenschutzgründen oder bei unvollständigen Remote-Kandidaten.Beispiele
Ports aller lokalen und entfernten Kandidaten auflisten
const pc = new RTCPeerConnection({
iceServers: [{ urls: 'stun:stun.l.google.com:19302' }]
});
pc.createDataChannel('test');
await pc.setLocalDescription(await pc.createOffer());
// Kurz warten, bis ICE-Kandidaten gesammelt wurden
await new Promise((r) => setTimeout(r, 2000));
const report = await pc.getStats();
report.forEach((stat) => {
if (stat.type === 'local-candidate' || stat.type === 'remote-candidate') {
console.log(`${stat.type} ${stat.candidateType} ${stat.protocol} ${stat.address ?? '?'}:${stat.port}`);
}
});
Port des aktiv genutzten Kandidatenpaars ermitteln
const getActivePorts = async (pc) => {
const report = await pc.getStats();
let pair;
report.forEach((s) => {
if (s.type === 'transport' && s.selectedCandidatePairId) {
pair = report.get(s.selectedCandidatePairId);
}
});
// Fallback für Browser ohne selectedCandidatePairId
if (!pair) {
report.forEach((s) => {
if (s.type === 'candidate-pair' && s.nominated && s.state === 'succeeded') pair = s;
});
}
if (!pair) return null;
const local = report.get(pair.localCandidateId);
const remote = report.get(pair.remoteCandidateId);
return { localPort: local?.port, remotePort: remote?.port };
};
// Nach Verbindungsaufbau aufrufen:
// console.log(await getActivePorts(pc));
TURN-Relay-Nutzung über Port erkennen
const report = await pc.getStats();
const relays = [...report.values()].filter(
(s) => s.type === 'local-candidate' && s.candidateType === 'relay'
);
for (const c of relays) {
const hinweis = c.port === 443 ? '(TLS/HTTPS-Port, firewallfreundlich)' : '';
console.log(`Relay über Port ${c.port} ${hinweis}`);
}
// Wichtig · Fallstricke
- Datenschutz: Wegen mDNS-Verschleierung (
*.local-Hostnamen) kannaddressbei Host-Kandidaten fehlen oder verschleiert sein.portist meist trotzdem gesetzt. Beide Werte sollte man vor der Verwendung prüfen. - Bei TCP-Kandidaten mit
tcpType: "active"ist der Port oft9, ein Platzhalter nach RFC 6544. Ein echter Zielport ist das nicht. portgibt den Port des Kandidaten an. Beirelay-Kandidaten ist das also der Port auf dem TURN-Server, nicht der Port des lokalen Sockets. Der Port zum TURN-Server steht (browserabhängig) inrelayProtocolbzw.url.- Statistiken sind Momentaufnahmen. Für aktuelle Werte muss
getStats()erneut aufgerufen werden. - Ältere Browserversionen verwendeten teils den Namen
portNumber. Bei älteren Zielplattformen empfiehlt sich ein Fallback wiestat.port ?? stat.portNumber.