Signatur
Beschreibung
Die schreibgeschützte Eigenschaft dtlsRole gehört zum Statistik-Wörterbuch RTCTransportStats, also zu Einträgen mit type === "transport" im RTCStatsReport, den RTCPeerConnection.getStats() liefert. Sie zeigt an, ob die lokale Seite den DTLS-Handshake als Client startet oder als Server darauf antwortet.
Welche Rolle eine Seite bekommt, wird über das SDP-Attribut a=setup ausgehandelt. Der Anbieter (Offerer) schickt meist actpass, der Antwortende (Answerer) legt sich dann auf active (wird DTLS-Client) oder passive (wird DTLS-Server) fest. Browser antworten normalerweise mit active. Deshalb ist in der Praxis der Answerer meist der Client und der Offerer der Server.
Mögliche Werte:
"client": Die lokale Seite startet den DTLS-Handshake."server": Die lokale Seite wartet auf den Handshake der Gegenseite."unknown": Die Rolle steht noch nicht fest, etwa weil die DTLS-Verhandlung noch nicht begonnen hat.
Die Eigenschaft ist vor allem bei der Fehlersuche nützlich, zum Beispiel wenn Verbindungen an Firewalls, TURN-Servern oder falsch umgeschriebenem SDP scheitern. Sie hilft auch bei Protokollierung und Überwachung, zusammen mit dtlsState, tlsVersion, dtlsCipher und srtpCipher.
Rückgabewert
undefined.Beispiele
DTLS-Rolle aus dem Statistik-Bericht auslesen
// pc ist eine bestehende, verbundene RTCPeerConnection
const getDtlsRole = async (pc) => {
const report = await pc.getStats();
for (const stats of report.values()) {
if (stats.type === 'transport') {
return stats.dtlsRole ?? 'nicht unterstützt';
}
}
return 'kein Transport gefunden';
};
console.log('DTLS-Rolle:', await getDtlsRole(pc));
Lokaler Test: Rollen von Offerer und Answerer vergleichen
const offerer = new RTCPeerConnection();
const answerer = new RTCPeerConnection();
// ICE-Kandidaten direkt austauschen
offerer.onicecandidate = ({ candidate }) => candidate && answerer.addIceCandidate(candidate);
answerer.onicecandidate = ({ candidate }) => candidate && offerer.addIceCandidate(candidate);
offerer.createDataChannel('test');
await offerer.setLocalDescription(await offerer.createOffer());
await answerer.setRemoteDescription(offerer.localDescription);
await answerer.setLocalDescription(await answerer.createAnswer());
await offerer.setRemoteDescription(answerer.localDescription);
// Warten, bis die Verbindung steht
await new Promise((resolve) => {
offerer.onconnectionstatechange = () => {
if (offerer.connectionState === 'connected') resolve();
};
});
const roleOf = async (pc) => {
const report = await pc.getStats();
return [...report.values()].find((s) => s.type === 'transport')?.dtlsRole;
};
console.log('Offerer:', await roleOf(offerer));
console.log('Answerer:', await roleOf(answerer));
Sicherheitsdaten des Transports für die Fehlersuche protokollieren
const logTransportSecurity = async (pc) => {
const report = await pc.getStats();
report.forEach((s) => {
if (s.type !== 'transport') return;
console.table({
dtlsRole: s.dtlsRole,
dtlsState: s.dtlsState,
tlsVersion: s.tlsVersion,
dtlsCipher: s.dtlsCipher,
srtpCipher: s.srtpCipher
});
});
};
// Alle 5 Sekunden prüfen, solange die Verbindung besteht
const timer = setInterval(() => {
if (pc.connectionState === 'closed') return clearInterval(timer);
logTransportSecurity(pc);
}, 5000);
// Wichtig · Fallstricke
- Browser-Unterstützung: Nicht jeder Browser liefert
dtlsRole. Chromium-basierte Browser unterstützen die Eigenschaft, in anderen Engines kann sie fehlen. Prüfe deshalb immer aufundefined, zum Beispiel mitstats.dtlsRole ?? "unbekannt". - Zeitpunkt: Vor dem Start oder während des DTLS-Handshakes ist der Wert oft
"unknown". Verlässlich ist er erst, wenndtlsStateden Wert"connected"hat. - Kein Wörterbuch-Objekt im Code:
RTCTransportStatsist keine Klasse, die du selbst erzeugen kannst. Du bekommst die Werte nur übergetStats(). Die Eigenschaft ist schreibgeschützt und steuert die Rolle nicht. - Rolle festlegen: Die Rolle lässt sich nur über das SDP-Attribut
a=setupbeeinflussen. Wer SDP von Hand umschreibt (SDP-Munging), riskiert, dass beide Seiten dieselbe Rolle wählen und der Handshake scheitert. - Bündelung: Bei
bundlePolicy: "max-bundle"(Standard in modernen Browsern) gibt es meist nur einen Transport-Eintrag. Ohne Bündelung kann es mehrere Einträge geben, jeweils mit eigenerdtlsRole.