Signatur
Beschreibung
Die schreibgeschützte Eigenschaft transport eines RTCSctpTransport-Objekts verweist auf den darunterliegenden RTCDtlsTransport. In WebRTC laufen alle RTCDataChannel-Verbindungen über SCTP, und SCTP wiederum läuft verschlüsselt über DTLS. Mit dieser Eigenschaft kommt man also von der Ebene der Datenkanäle zur Verschlüsselungs- und Transportebene.
Brauchbar ist das vor allem für Diagnose und Überwachung: Über transport.state sieht man, ob der DTLS-Handshake abgeschlossen ist ("connected") oder fehlgeschlagen ist ("failed"). transport.getRemoteCertificates() liefert die Zertifikate der Gegenstelle. Und über transport.iceTransport gelangt man zur ICE-Ebene, also zum gewählten Kandidatenpaar und zum Zustand der Netzwerkverbindung.
Man erreicht den RTCSctpTransport über RTCPeerConnection.sctp. Diese Eigenschaft ist null, bis SCTP ausgehandelt wurde. Das passiert erst, wenn mindestens ein Datenkanal existiert und die lokale und entfernte Beschreibung gesetzt sind. Erst danach kann man transport sinnvoll auslesen.
Rückgabewert
RTCDtlsTransport, über den die SCTP-Pakete der Datenkanäle laufen. Bei Bundling (Normalfall) ist das derselbe DTLS-Transport, den auch die Medienspuren nutzen.Beispiele
DTLS-Zustand des Datenkanal-Transports auslesen
const pc = new RTCPeerConnection();
const channel = pc.createDataChannel('chat');
// ... Signalisierung: createOffer/setLocalDescription/setRemoteDescription ...
channel.addEventListener('open', () => {
const dtls = pc.sctp?.transport;
if (dtls) {
console.log('DTLS-Zustand:', dtls.state);
}
});
Zustandswechsel und Fehler des DTLS-Transports überwachen
const watchDataTransport = (pc) => {
const dtls = pc.sctp?.transport;
if (!dtls) {
console.warn('SCTP noch nicht ausgehandelt');
return;
}
dtls.addEventListener('statechange', () => {
console.log('DTLS-Zustand geändert:', dtls.state);
if (dtls.state === 'failed') {
console.error('DTLS-Handshake fehlgeschlagen – Verbindung neu aufbauen');
}
});
dtls.addEventListener('error', (event) => {
console.error('DTLS-Fehler:', event.error?.message);
});
};
// Aufruf, sobald die Beschreibungen gesetzt sind
watchDataTransport(pc);
Über transport zur ICE-Ebene und zum Kandidatenpaar
const logDataPath = (pc) => {
const ice = pc.sctp?.transport?.iceTransport;
if (!ice) return;
console.log('ICE-Zustand:', ice.state);
const pair = ice.getSelectedCandidatePair?.();
if (pair) {
console.log(`Lokal: ${pair.local.type} ${pair.local.protocol}`);
console.log(`Entfernt: ${pair.remote.type} ${pair.remote.protocol}`);
}
};
logDataPath(pc);
Zertifikat der Gegenstelle prüfen
const dtls = pc.sctp?.transport;
if (dtls?.state === 'connected') {
const certs = dtls.getRemoteCertificates();
console.log('Anzahl entfernter Zertifikate:', certs.length);
console.log('Erstes Zertifikat (DER, Bytes):', certs[0]?.byteLength);
}
// Wichtig · Fallstricke
pc.sctpist anfangsnull: Ohne Datenkanal im Angebot oder vorsetRemoteDescription()gibt es keinenRTCSctpTransport. Deshalb Optional Chaining (pc.sctp?.transport) verwenden.- Nur lesbar: Wenn man
transportetwas zuweist, hat das keine Wirkung. Im Strict Mode wirft es einenTypeError. - Geteilter Transport: Mit
bundlePolicy: "max-bundle"(bzw. dem üblichen Bundling) ist der zurückgegebeneRTCDtlsTransportmeist identisch mitRTCRtpSender.transportder Medienspuren. Ein Fehlschlag hier betrifft dann Audio, Video und Daten gleichermaßen. - Browser-Kompatibilität:
RTCSctpTransportwird in Firefox erst ab Version 113 vollständig unterstützt.getSelectedCandidatePair()aufRTCIceTransportfehlt in einigen Browsern. Vor dem Aufruf per Feature-Erkennung prüfen. - Sicherheit: Die Zertifikate aus
getRemoteCertificates()sind meist selbst signiert. Die Identität der Gegenstelle ist erst gesichert, wenn man den Fingerabdruck mit dem aus der Signalisierung vergleicht und die Signalisierung selbst vertrauenswürdig ist.