Verwenden von WebRTC-Datenkanälen
In diesem Leitfaden werden wir untersuchen, wie man einen Datenkanal zu einer Peer-Verbindung hinzufügt, der dann zum sicheren Austausch beliebiger Daten verwendet werden kann, also jeder Art von Daten, die wir möchten, in jedem Format, das wir wählen.
Hinweis:
Da alle WebRTC-Komponenten verschlüsselt werden müssen, sind alle auf einem RTCDataChannel
übertragenen Daten automatisch durch Datagram Transport Layer Security (DTLS) gesichert. Siehe Sicherheit unten für weitere Informationen.
Erstellen eines Datenkanals
Der zugrundeliegende Datentransport, der von dem RTCDataChannel
verwendet wird, kann auf zwei Arten erstellt werden:
- Lassen Sie WebRTC den Transport erstellen und dem entfernten Peer für Sie ankündigen (indem es ein
datachannel
Ereignis empfängt). Dies ist der einfache Weg und funktioniert für eine Vielzahl von Anwendungsfällen, ist jedoch möglicherweise nicht flexibel genug für Ihre Anforderungen. - Schreiben Sie Ihren eigenen Code, um den Datentransport auszuhandeln, und schreiben Sie Ihren eigenen Code, um das andere Peer darauf hinzuweisen, dass es sich mit dem neuen Kanal verbinden muss.
Schauen wir uns jede dieser Fälle an, beginnend mit dem ersten, der am häufigsten vorkommt.
Automatische Aushandlung
Oft können Sie die Peer-Verbindung die Aushandlung der RTCDataChannel
Verbindung für Sie übernehmen lassen. Dazu rufen Sie createDataChannel()
auf, ohne einen Wert für die negotiated
-Eigenschaft anzugeben, oder indem Sie die Eigenschaft mit einem Wert von false
angeben. Dies löst automatisch die RTCPeerConnection
aus, die Verhandlungen für Sie zu übernehmen, wodurch der entfernte Peer einen Datenkanal erstellt und die beiden über das Netzwerk verbindet.
Das RTCDataChannel
-Objekt wird sofort von createDataChannel()
zurückgegeben; Sie können erkennen, wann die Verbindung erfolgreich hergestellt wurde, indem Sie auf das open
Ereignis achten, das an das RTCDataChannel
gesendet wird.
let dataChannel = pc.createDataChannel("MyApp Channel");
dataChannel.addEventListener("open", (event) => {
beginTransmission(dataChannel);
});
Manuelle Aushandlung
Um die Datenkanalverbindung manuell auszuhandeln, müssen Sie zuerst ein neues RTCDataChannel
Objekt mit der createDataChannel()
Methode auf der RTCPeerConnection
erstellen, wobei in den Optionen eine negotiated
-Eigenschaft auf true
gesetzt ist. Dies signalisiert der Peer-Verbindung, dass sie nicht versuchen soll, den Kanal in Ihrem Auftrag auszuhandeln.
Dann verhandeln Sie die Verbindung extern, zum Beispiel über einen Webserver oder andere Mittel. Dieser Prozess sollte dem entfernten Peer signalisieren, dass es seinen eigenen RTCDataChannel
mit ebenfalls auf true
gesetzter negotiated
-Eigenschaft und mit derselben id
erstellen soll. Dies wird die beiden Objekte über die RTCPeerConnection
verbinden.
let dataChannel = pc.createDataChannel("MyApp Channel", {
negotiated: true,
});
dataChannel.addEventListener("open", (event) => {
beginTransmission(dataChannel);
});
requestRemoteChannel(dataChannel.id);
In diesem Codebeispiel wird der Kanal mit negotiated
auf true
gesetzt erstellt, dann wird eine Funktion namens requestRemoteChannel()
verwendet, um die Aushandlung auszulösen, um einen entfernten Kanal mit derselben ID wie der lokale Kanal zu erstellen.
Auf diese Weise können Sie Datenkanäle mit jedem Peer erstellen, die unterschiedliche Eigenschaften verwenden, und Kanäle deklarativ erstellen, indem Sie denselben Wert für id
verwenden.
Pufferung
WebRTC-Datenkanäle unterstützen das Puffern von ausgehenden Daten. Dies wird automatisch gehandhabt. Während es keine Möglichkeit gibt, die Größe des Puffers zu steuern, können Sie erfahren, wie viele Daten derzeit gepuffert sind, und Sie können wählen, dass Sie von einem Ereignis benachrichtigt werden, wenn der Puffer beginnt, an angestauten Daten abzulaufen. Dies macht es einfach, effiziente Routinen zu schreiben, die sicherstellen, dass immer Daten bereit zum Senden sind, ohne den Speicher übermäßig zu beanspruchen oder den Kanal vollständig zu überlasten.
Verstehen der Nachrichtenbegrenzungen
Sie sollten die Nachrichtengrößen moderat klein halten. Während die meisten modernen Browser unterstützen, Nachrichten von mindestens 256 Kilobyte zu senden, gibt es Nachteile beim Senden großer Nachrichten, insbesondere wenn Nachrichtenverschränkung nicht verfügbar ist. Ohne Nachrichtenverschränkung (wie definiert in RFC 8260) kann das Senden einer großen Nachricht über einen Datenkanal Head-of-Line-Blocking verursachen, was wiederum die Latenz von Nachrichten auf anderen Datenkanälen negativ beeinflussen kann.
Die maximale Nachrichtengröße kann mit dem SDP-Attribut max-message-size
ausgehandelt werden, wie in RFC 8841 definiert. Dieses Attribut erlaubt es jedem Peer, die maximale Größe einer SCTP-Benutzernachricht zu deklarieren, die es bereit ist zu empfangen. Durch die Aushandlung dieses Wertes können Endpunkte vermeiden, Nachrichten zu senden, die größer sind, als der andere Peer verarbeiten kann. Wenn das max-message-size
Attribut nicht im SDP vorhanden ist, wird ein Standardwert von 64 Kilobytes angenommen. Ein Wert von 0 zeigt an, dass der Endpunkt Nachrichten beliebiger Größe verarbeiten kann, nur beschränkt durch verfügbaren Speicher.
Sicherheit
Alle mit WebRTC übertragenen Daten sind verschlüsselt. Im Fall von RTCDataChannel
wird die Verschlüsselung durch Datagram Transport Layer Security (DTLS) durchgeführt, das auf Transport Layer Security (TLS) basiert. Da TLS verwendet wird, um jede HTTPS-Verbindung zu sichern, sind alle Daten, die Sie über einen Datenkanal senden, genauso sicher wie alle anderen Daten, die vom Browser des Nutzers gesendet oder empfangen werden.
Grundlegender ist, dass WebRTC eine Peer-to-Peer-Verbindung zwischen zwei Benutzeragenten ist, sodass die Daten niemals über den Web- oder Anwendungsserver geleitet werden. Dies verringert die Möglichkeiten, dass die Daten abgefangen werden.