Das Senden von Daten zwischen zwei Browsern für Kommunikation, Gaming oder Dateiübertragung kann ein ziemlich aufwendiger Vorgang sein. Es ist erforderlich, einen Server zum Weiterleiten von Daten einzurichten und zu bezahlen und ihn gegebenenfalls auf mehrere Rechenzentren auszuweiten. In diesem Szenario kann es zu einer hohen Latenz kommen und es ist schwierig, die Daten zu schützen.
Diese Probleme können durch die Verwendung der RTCDataChannel
API von WebRTC behoben werden, um Daten direkt von einem Peer an einen anderen zu übertragen. In diesem Artikel erfahren Sie, wie Sie Datenkanäle einrichten und verwenden, und welche Anwendungsfälle im Web derzeit häufig vorkommen.
Warum ein weiterer Datenkanal?
Es gibt WebSocket, AJAX und Server Sent Events. Warum brauchen wir einen weiteren Kommunikationskanal? WebSocket ist bidirektional, aber alle diese Technologien sind für die Kommunikation zu oder von einem Server konzipiert.
RTCDataChannel
verfolgt einen anderen Ansatz:
- Sie funktioniert mit der
RTCPeerConnection
API, die eine Peer-to-Peer-Verbindung ermöglicht. Das kann zu einer geringeren Latenz führen, da es keinen Zwischenserver und weniger „Hops“ gibt. RTCDataChannel
verwendet das Stream Control Transmission Protocol (SCTP), das eine konfigurierbare Auslieferungssemantik – die Lieferung in einer anderen Reihenfolge und die Neuübertragung – ermöglicht.
RTCDataChannel
ist jetzt mit SCTP-Unterstützung auf dem Computer und Android in Google Chrome, Opera und Firefox verfügbar.
Ein Vorbehalt: Signalisierung, STUN und TURN
WebRTC ermöglicht die Peer-to-Peer-Kommunikation, benötigt aber trotzdem Server für die Signalisierung, um Medien- und Netzwerkmetadaten auszutauschen und eine Peer-Verbindung zu starten.
WebRTC unterstützt NATs und Firewalls mit:
- Das ICE-Framework, um den bestmöglichen Netzwerkpfad zwischen Peers herzustellen.
- STUN-Server, um für jeden Peer eine öffentlich zugängliche IP-Adresse und einen Port zu ermitteln.
- TURN-Server, wenn die direkte Verbindung fehlschlägt und ein Daten-Relay erforderlich ist.
Weitere Informationen zur Funktionsweise von WebRTC mit Servern für Signalisierung und Networking finden Sie unter WebRTC in der Praxis: STUN, TURN und Signalisierung.
Die Funktionen
Die RTCDataChannel
API unterstützt eine flexible Reihe von Datentypen. Die API wurde entwickelt, um WebSocket genau nachzuahmen. RTCDataChannel
unterstützt Strings sowie einige der Binärtypen in JavaScript, z. B. Blob, ArrayBuffer und ArrayBufferView. Diese Typen können bei der Dateiübertragung und bei Multiplayer-Spielen hilfreich sein.
RTCDataChannel
kann im unzuverlässigen und ungeordneten Modus (analog zum User Datagram Protocol oder UDP), im zuverlässigen und geordneten Modus (analog zum Transmission Control Protocol oder TCP) und in teilweise zuverlässigen Modi arbeiten:
- Der zuverlässige und geordnete Modus garantiert die Übertragung von Nachrichten und auch die Reihenfolge, in der sie zugestellt werden. Dies führt zu zusätzlichem Overhead und kann diesen Modus verlangsamen.
- Im Modus „Unzuverlässig und unsortiert“ kann nicht garantiert werden, dass jede Nachricht ankommt und in welcher Reihenfolge sie ankommt. Dadurch wird der Overhead reduziert und dieser Modus kann viel schneller arbeiten.
- Der teilweise zuverlässige Modus garantiert die Übertragung der Nachricht unter einer bestimmten Bedingung, z. B. einem Zeitlimit für die Wiederholungsübertragung oder einer maximalen Anzahl von Wiederholungsübertragungen. Auch die Reihenfolge der Nachrichten ist konfigurierbar.
Die Leistung der ersten beiden Modi ist ungefähr gleich, wenn keine Paketverluste auftreten. Im zuverlässigen und geordneten Modus führt ein verlorenes Paket jedoch dazu, dass andere Pakete dahinter blockiert werden. Das verlorene Paket ist möglicherweise veraltet, wenn es noch einmal gesendet und ankommt. Es ist natürlich möglich, innerhalb derselben App mehrere Datenkanäle zu verwenden, die jeweils ihre eigenen zuverlässigen oder unzuverlässigen Semantiken haben.
Hier ist eine hilfreiche Tabelle aus High Performance Browser Networking von Ilya Grigorik:
TCP | UDP | SCTP | |
Zuverlässigkeit | Zuverlässig | Unzuverlässig | Konfigurierbar |
Lieferung | Bestellt | Unsortiert | Konfigurierbar |
Übertragung | Byte-orientiert | Nachrichtenorientiert | Nachrichtenorientiert |
Ablaufsteuerung | Ja | Nein | Ja |
Überlastungssteuerung | Ja | Nein | Ja |
Als Nächstes erfahren Sie, wie Sie RTCDataChannel
für den zuverlässigen und geordneten oder den unzuverlässigen und ungeordneten Modus konfigurieren.
Datenkanäle konfigurieren
Es gibt mehrere einfache Demos von RTCDataChannel
online:
In diesen Beispielen stellt der Browser eine Peer-Verbindung zu sich selbst her, erstellt dann einen Datenkanal und sendet eine Nachricht über die Peer-Verbindung. Es wird dann ein Datenkanal erstellt und die Nachricht über die Peer-Verbindung gesendet. Ihre Nachricht wird schließlich im Feld auf der anderen Seite der Seite angezeigt.
Der Code dafür ist kurz:
const peerConnection = new RTCPeerConnection();
// Establish your peer connection using your signaling channel here
const dataChannel =
peerConnection.createDataChannel("myLabel", dataChannelOptions);
dataChannel.onerror = (error) => {
console.log("Data Channel Error:", error);
};
dataChannel.onmessage = (event) => {
console.log("Got Data Channel Message:", event.data);
};
dataChannel.onopen = () => {
dataChannel.send("Hello World!");
};
dataChannel.onclose = () => {
console.log("The Data Channel is Closed");
};
Das dataChannel
-Objekt wird aus einer bereits hergestellten Peer-Verbindung erstellt. Sie kann vor oder nach der Signalisierung erstellt werden. Geben Sie dann ein Label ein, um diesen Kanal von anderen zu unterscheiden, und eine Reihe optionaler Konfigurationseinstellungen:
const dataChannelOptions = {
ordered: false, // do not guarantee order
maxPacketLifeTime: 3000, // in milliseconds
};
Es ist auch möglich, eine maxRetransmits
-Option hinzuzufügen (die Anzahl der Versuche, bevor ein Fehler auftritt). Sie können jedoch nur maxRetransmits oder maxPacketLifeTime angeben, nicht beides. Legen Sie für die UDP-Semantik maxRetransmits
auf 0
und ordered
auf false
fest. Weitere Informationen finden Sie in den folgenden IETF-RFCs: Stream Control Transmission Protocol und Stream Control Transmission Protocol Partial Reliability Extension.
ordered
: ob die Reihenfolge der Daten im Datenkanal garantiert werden sollmaxPacketLifeTime
: Maximale Zeit, nach der eine fehlgeschlagene Nachricht noch einmal gesendet werden kannmaxRetransmits
: Die maximale Anzahl der Wiederholungsversuche für eine fehlgeschlagene Nachrichtprotocol
: Ermöglicht die Verwendung eines Subprotokolls, das Metainformationen für die App bereitstellt.negotiated
: Wenn dieser Parameter auf „wahr“ gesetzt ist, wird die automatische Einrichtung eines Datenkanals auf dem anderen Peer aufgehoben. Sie können dann selbst einen Datenkanal mit derselben ID auf der anderen Seite erstellen.id
: Hiermit können Sie eine eigene ID für den Kanal angeben, die nur in Kombination mitnegotiated
=true
verwendet werden kann.
Die meisten Nutzer benötigen nur die ersten drei Optionen: ordered
, maxPacketLifeTime
und maxRetransmits
. Bei SCTP (wird jetzt von allen Browsern verwendet, die WebRTC unterstützen) sind „zuverlässig“ und „geordnet“ standardmäßig aktiviert. Es ist sinnvoll, unsichere und ungeordnete Verbindungen zu verwenden, wenn Sie die vollständige Kontrolle über die App-Ebene haben möchten. In den meisten Fällen ist jedoch eine teilweise Zuverlässigkeit hilfreich.
Wie bei WebSocket löst RTCDataChannel
Ereignisse aus, wenn eine Verbindung hergestellt oder geschlossen wird, Fehler auftreten oder eine Nachricht vom anderen Peer empfangen wird.
Ist es sicher?
Die Verschlüsselung ist für alle WebRTC-Komponenten obligatorisch. Bei RTCDataChannel
werden alle Daten mit Datagram Transport Layer Security (DTLS) geschützt. DTLS ist eine Ableitung von SSL. Ihre Daten sind also genauso sicher wie bei einer standardmäßigen SSL-basierten Verbindung. DTLS ist standardisiert und in allen Browsern integriert, die WebRTC unterstützen. Weitere Informationen finden Sie im Wireshark-Wiki.
Ändern Sie Ihre Einstellung zu Daten
Die Verarbeitung großer Datenmengen kann in JavaScript eine Herausforderung sein. Wie die Entwickler von Sharefest hervorhoben, erforderte dies eine neue Herangehensweise an Daten. Wenn Sie eine Datei übertragen, die größer als der verfügbare Arbeitsspeicher ist, müssen Sie sich über neue Möglichkeiten zum Speichern dieser Informationen Gedanken machen. Hier kommen Technologien wie die FileSystem API ins Spiel, wie Sie gleich sehen werden.
App für die Dateifreigabe entwickeln
Mit RTCDataChannel
können Sie jetzt eine Webanwendung erstellen, mit der Dateien im Browser freigegeben werden können. Wenn Sie auf RTCDataChannel
aufbauen, werden die übertragenen Dateidaten verschlüsselt und die Server eines App-Anbieters werden nicht verwendet. Diese Funktion in Kombination mit der Möglichkeit, eine Verbindung zu mehreren Clients herzustellen, um die Freigabe zu beschleunigen, macht die WebRTC-Dateifreigabe zu einem starken Kandidaten für das Web.
Für eine erfolgreiche Übertragung sind mehrere Schritte erforderlich:
- Dateien in JavaScript mit der File API lesen
- Peer-Verbindung zwischen Clients mit
RTCPeerConnection
herstellen - Erstelle einen Datenkanal zwischen Kunden mit
RTCDataChannel
.
Beim Senden von Dateien über RTCDataChannel
sind einige Punkte zu beachten:
- Dateigröße:Wenn die Dateigröße relativ klein ist und als einzelnes Blob gespeichert und geladen werden kann, können Sie sie mit der File API in den Arbeitsspeicher laden und dann unverändert über einen zuverlässigen Kanal senden. Beachten Sie jedoch, dass Browser die maximale Übertragungsgröße begrenzen. Je größer die Datei ist, desto schwieriger wird es. Wenn ein Chunking-Mechanismus erforderlich ist, werden Datei-Chunks geladen und zusammen mit
chunkID
-Metadaten an einen anderen Peer gesendet, damit dieser sie erkennen kann. In diesem Fall müssen Sie die Chunks zuerst im Offlinespeicher speichern (z. B. mit der FileSystem API) und erst dann auf dem Laufwerk des Nutzers, wenn Sie die Datei vollständig haben. - Chunk-Größe:Dies sind die kleinsten „Atome“ von Daten für Ihre App. Das Chunking ist erforderlich, da derzeit eine Beschränkung der Sendegröße gilt. Dies wird jedoch in einer zukünftigen Version von Datenkanälen behoben. Die aktuelle Empfehlung für die maximale Größe von Chunks beträgt 64 KiB.
Sobald die Datei vollständig auf die andere Seite übertragen wurde, kann sie mit einem Anker-Tag heruntergeladen werden:
function saveFile(blob) {
const link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = 'File Name';
link.click();
};
Diese Dateifreigabe-Apps auf PubShare und GitHub verwenden diese Methode. Beide sind Open Source und bieten eine gute Grundlage für eine Dateifreigabe-App, die auf RTCDataChannel
basiert.
Was können Sie also tun?
RTCDataChannel
eröffnet neue Möglichkeiten, Apps für die Dateifreigabe, Multiplayer-Gaming und die Bereitstellung von Inhalten zu erstellen.
- Peer-to-Peer-Dateifreigabe wie oben beschrieben
- Mehrspielerspiele in Kombination mit anderen Technologien wie WebGL, wie in BananaBread von Mozilla
- Die Content Delivery wird von PeerCDN neu erfunden, einem Framework, das Web-Assets über Peer-to-Peer-Datenkommunikation bereitstellt
Apps anders entwickeln
Sie können jetzt ansprechendere Apps anbieten, indem Sie über RTCDataChannel
leistungsstarke Verbindungen mit niedriger Latenz nutzen. Frameworks wie PeerJS und das PubNub WebRTC SDK erleichtern die Implementierung von RTCDataChannel
und die API wird jetzt plattformübergreifend unterstützt.
Die Einführung von RTCDataChannel
kann die Art und Weise verändern, wie Sie die Datenübertragung im Browser betrachten.