Start · Sprachen · JavaScript · Referenz · RTCTransportStats.dtlsRole

RTCTransportStats.dtlsRole

Eigenschaft

Gibt als String (<code>"client"</code>, <code>"server"</code> oder <code>"unknown"</code>) an, welche Rolle die <code>RTCPeerConnection</code> im DTLS-Handshake des Transports übernimmt.

seit JavaScript Uneinheitliche Browser-Unterstützung (v. a. Chromi Kategorie: webapi

Signatur

RTCTransportStats.dtlsRole

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

Typ
"client" | "server" | "unknown" | undefined
Beschreibung
Die DTLS-Rolle der lokalen Seite als String. Wenn der Browser die Eigenschaft nicht unterstützt, fehlt sie im Statistik-Objekt, und der Wert ist 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));
DTLS-Rolle: server

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));
Offerer: server Answerer: client

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);
┌────────────┬──────────────────────────────────┐ │ dtlsRole │ client │ │ dtlsState │ connected │ │ tlsVersion │ FEFD │ │ ... │ ... │ └────────────┴──────────────────────────────────┘

// 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 auf undefined, zum Beispiel mit stats.dtlsRole ?? "unbekannt".
  • Zeitpunkt: Vor dem Start oder während des DTLS-Handshakes ist der Wert oft "unknown". Verlässlich ist er erst, wenn dtlsState den Wert "connected" hat.
  • Kein Wörterbuch-Objekt im Code: RTCTransportStats ist keine Klasse, die du selbst erzeugen kannst. Du bekommst die Werte nur über getStats(). Die Eigenschaft ist schreibgeschützt und steuert die Rolle nicht.
  • Rolle festlegen: Die Rolle lässt sich nur über das SDP-Attribut a=setup beeinflussen. 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 eigener dtlsRole.