WebTransport verwenden

WebTransport ist eine API, die bidirektionales Client-Server-Messaging mit niedriger Latenz ermöglicht. Hier erfahren Sie mehr über die Anwendungsfälle und darüber, wie Sie Feedback zur Zukunft der Implementierung geben können.

Hintergrund

Was ist WebTransport?

WebTransport ist eine Web-API, die das HTTP/3-Protokoll für bidirektionalen Transport verwendet. Sie ist für die bidirektionale Kommunikation zwischen einem Webclient und einem HTTP/3-Server vorgesehen. Es unterstützt das Senden von Daten sowohl unzuverlässig über seine Datagram APIs als auch zuverlässig über seine Streams APIs.

Datagramme sind ideal für das Senden und Empfangen von Daten, für die keine starken Zustellungsgarantien erforderlich sind. Einzelne Datenpakete sind durch die maximale Übertragungseinheit (MTU) der zugrunde liegenden Verbindung begrenzt und werden möglicherweise nicht erfolgreich übertragen. Bei der Übertragung können sie in einer beliebigen Reihenfolge ankommen. Aufgrund dieser Eigenschaften sind die Datagram APIs ideal für die Best-Effort-Datenübertragung mit niedriger Latenz. Sie können sich Datagramme als UDP-Nachrichten (User Datagram Protocol) vorstellen, die verschlüsselt und von Überlastungen kontrolliert werden.

Die Stream-APIs bieten dagegen eine zuverlässige, geordnete Datenübertragung. Sie eignen sich gut für Szenarien, in denen Sie einen oder mehrere Streams geordneter Daten senden oder empfangen müssen. Die Verwendung mehrerer WebTransport-Streams entspricht dem Aufbau mehrerer TCP-Verbindungen. Da HTTP/3 jedoch das schlankere QUIC-Protokoll im Hintergrund verwendet, können sie mit weniger Aufwand geöffnet und geschlossen werden.

Anwendungsfälle

Dies ist eine kleine Liste mit Möglichkeiten, wie Entwickler WebTransport verwenden können.

  • Regelmäßiges Senden des Spielstatus mit minimaler Latenz über kleine, unzuverlässige Nachrichten außer der Reihenfolge an einen Server
  • Der Empfang von Medienstreams, die von einem Server mit minimaler Latenz übertragen wurden, unabhängig von anderen Datenstreams
  • Benachrichtigungen von einem Server empfangen, während eine Webseite geöffnet ist.

Wir würden gern weitere Informationen dazu erhalten, wie du WebTransport verwenden möchtest.

Unterstützte Browser

Unterstützte Browser

  • 97
  • 97
  • 114
  • x

Quelle

Wie bei allen Funktionen ohne universelle Browserunterstützung hat sich auch hier die defensive Codierung mithilfe der Funktionserkennung bewährt.

Aktueller Status

Step Status
1. Erklärende Erklärung erstellen Abschließen
2. Ersten Entwurf der Spezifikation erstellen Abschließen
3. Feedback einholen und Design iterieren Abschließen
4. Ursprungstest Abschließen
5. Launch Chromium 97

Beziehung von WebTransport zu anderen Technologien

Ist WebTransport ein Ersatz für WebSockets?

Kann sein. In einigen Anwendungsfällen können entweder WebSockets oder WebTransport gültige Kommunikationsprotokolle sein.

Die WebSocket-Kommunikation richtet sich nach einem einzelnen, zuverlässigen, geordneten Nachrichtenstream, was für einige Arten von Kommunikationsanforderungen gut geeignet ist. Wenn Sie diese Eigenschaften benötigen, können Sie diese auch über die Streams-APIs von WebTransport bereitstellen. Im Vergleich dazu bieten die Datagram APIs von WebTransport eine Übermittlung mit niedriger Latenz, ohne Gewährleistungen hinsichtlich Zuverlässigkeit oder Bestellung. Daher sind sie kein direkter Ersatz für WebSockets.

Wenn Sie WebTransport, die Datagram APIs oder mehrere gleichzeitige Streams API-Instanzen verwenden, müssen Sie sich keine Gedanken über die Head-of-Line-Blockierung machen, die ein Problem bei WebSockets darstellen kann. Darüber hinaus ergeben sich beim Herstellen neuer Verbindungen Leistungsvorteile, da der zugrunde liegende QUIC-Handshake schneller ist als TCP über TLS.

WebTransport ist Teil eines neuen Spezifikationsentwurfs. Daher ist das WebSocket-Ökosystem für Client- und Serverbibliotheken derzeit wesentlich robuster. Wenn Sie etwas benötigen, das mit gängigen Server-Setups und umfassenden Web-Client-Unterstützung einsatzbereit ist, ist WebSockets heute die bessere Wahl.

Ist WebTransport dasselbe wie eine UDP Socket API?

Nein. WebTransport ist keine UDP Socket API. Während WebTransport HTTP/3 nutzt, das wiederum UDP „unter der Haube“ nutzt, hat WebTransport Anforderungen in Bezug auf Verschlüsselung und Überlastung, sodass es mehr ist als eine einfache UDP Socket API.

Ist WebTransport eine Alternative zu WebRTC-Datenkanälen?

Ja, für Client-Server-Verbindungen. WebTransport nutzt viele der Eigenschaften von WebRTC-Datenkanälen, wobei sich die zugrunde liegenden Protokolle jedoch unterscheiden.

Im Allgemeinen ist für den Betrieb eines HTTP/3-kompatiblen Servers weniger Einrichtung und Konfiguration erforderlich als bei einem WebRTC-Server. Dieser erfordert das Verständnis mehrerer Protokolle (ICE, DTLS und SCTP), um einen funktionierenden Transport zu ermöglichen. WebRTC umfasst viele weitere Faktoren, die zu fehlgeschlagenen Verhandlungen zwischen Client und Server führen könnten.

Die WebTransport API wurde im Hinblick auf die Anwendungsfälle von Webentwicklern entwickelt und sollte eher wie das Schreiben von Code für moderne Webplattformen aussehen als mit den Datenkanalschnittstellen von WebRTC. Im Gegensatz zu WebRTC wird WebTransport innerhalb von Web Workers unterstützt. Damit können Sie Client-Server-Kommunikation unabhängig von einer bestimmten HTML-Seite durchführen. Da WebTransport eine Streams-kompatible Schnittstelle bereitstellt, unterstützt es Optimierungen rund um den Hintergrund.

Wenn Sie jedoch bereits einen funktionierenden WebRTC-Client/Server haben, mit dem Sie zufrieden sind, bietet der Wechsel zu WebTransport möglicherweise nicht viele Vorteile.

Ausprobieren

Am besten lässt sich mit WebTransport experimentieren, indem ein kompatibler HTTP/3-Server gestartet wird. Sie können diese Seite dann mit einem grundlegenden JavaScript-Client verwenden, um die Client/Server-Kommunikation zu testen.

Außerdem steht unter webtransport.day ein von der Community gepflegter Echo-Server zur Verfügung.

API verwenden

WebTransport wurde auf Basis moderner Webplattform-Primitive entwickelt, z. B. der Streams API. Sie basiert stark auf Versprechen und funktioniert gut mit async und await.

Die aktuelle WebTransport-Implementierung in Chromium unterstützt drei verschiedene Arten von Traffic: Datagramme sowie sowohl unidirektionale als auch bidirektionale Streams.

Verbindung zu einem Server herstellen

Sie können eine Verbindung zu einem HTTP/3-Server herstellen, indem Sie eine WebTransport-Instanz erstellen. Das Schema der URL sollte https sein. Sie müssen die Portnummer explizit angeben.

Du solltest das Promise ready verwenden, um auf den Aufbau der Verbindung zu warten. Dieses Versprechen wird erst nach Abschluss der Einrichtung eingehalten und wird abgelehnt, wenn die Verbindung in der QUIC/TLS-Phase fehlschlägt.

Das Versprechen closed wird erfüllt, wenn die Verbindung normal beendet wird, und lehnt ab, wenn die Verbindung unerwartet geschlossen wurde.

Wenn der Server die Verbindung aufgrund eines Clientinformationen-Fehlers ablehnt (z.B. weil der URL-Pfad ungültig ist), lehnt closed die Verbindung ab, während ready noch nicht behoben ist.

const url = 'https://example.com:4999/foo/bar';
const transport = new WebTransport(url);

// Optionally, set up functions to respond to
// the connection closing:
transport.closed.then(() => {
  console.log(`The HTTP/3 connection to ${url} closed gracefully.`);
}).catch((error) => {
  console.error(`The HTTP/3 connection to ${url} closed due to ${error}.`);
});

// Once .ready fulfills, the connection can be used.
await transport.ready;

Datagram-APIs

Sobald Sie eine WebTransport-Instanz haben, die mit einem Server verbunden ist, können Sie über sie diskrete Datenbits, sogenannte Datagrams, senden und empfangen.

Der writeable-Getter gibt eine WritableStream zurück, mit der ein Webclient Daten an den Server senden kann. Der Getter readable gibt ein ReadableStream zurück, das es Ihnen ermöglicht, auf Daten vom Server zu warten. Beide Streams sind grundsätzlich unzuverlässig. Es ist also möglich, dass die von Ihnen geschriebenen Daten nicht vom Server empfangen werden und umgekehrt.

Bei beiden Arten von Streams werden Uint8Array-Instanzen für die Datenübertragung verwendet.

// Send two datagrams to the server.
const writer = transport.datagrams.writable.getWriter();
const data1 = new Uint8Array([65, 66, 67]);
const data2 = new Uint8Array([68, 69, 70]);
writer.write(data1);
writer.write(data2);

// Read datagrams from the server.
const reader = transport.datagrams.readable.getReader();
while (true) {
  const {value, done} = await reader.read();
  if (done) {
    break;
  }
  // value is a Uint8Array.
  console.log(value);
}

Streams-APIs

Sobald du eine Verbindung zum Server hergestellt hast, kannst du mit WebTransport auch Daten über die Streams APIs senden und empfangen.

Jeder Block aller Streams ist ein Uint8Array. Im Gegensatz zu den Datagram APIs sind diese Streams zuverlässig. Da jeder Stream unabhängig ist, kann die Reihenfolge der Daten in den verschiedenen Streams nicht garantiert werden.

WebTransportSendStream

Ein WebTransportSendStream wird vom Webclient mit der Methode createUnidirectionalStream() einer WebTransport-Instanz erstellt, die ein Promise für das WebTransportSendStream zurückgibt.

Verwenden Sie die Methode close() des WritableStreamDefaultWriter, um die zugehörige HTTP/3-Verbindung zu trennen. Der Browser versucht, alle ausstehenden Daten zu senden, bevor die zugehörige Verbindung tatsächlich geschlossen wird.

// Send two Uint8Arrays to the server.
const stream = await transport.createUnidirectionalStream();
const writer = stream.writable.getWriter();
const data1 = new Uint8Array([65, 66, 67]);
const data2 = new Uint8Array([68, 69, 70]);
writer.write(data1);
writer.write(data2);
try {
  await writer.close();
  console.log('All data has been sent.');
} catch (error) {
  console.error(`An error occurred: ${error}`);
}

Verwende in ähnlicher Weise die Methode abort() von WritableStreamDefaultWriter, um eine RESET\_STREAM an den Server zu senden. Wenn Sie abort() verwenden, verwirft der Browser möglicherweise alle ausstehenden Daten, die noch nicht gesendet wurden.

const ws = await transport.createUnidirectionalStream();
const writer = ws.getWriter();
writer.write(...);
writer.write(...);
await writer.abort();
// Not all the data may have been written.

WebTransportReceiveStream

Ein WebTransportReceiveStream wird vom Server initiiert. Das Abrufen einer WebTransportReceiveStream ist für einen Webclient in zwei Schritten erforderlich. Zuerst wird das incomingUnidirectionalStreams-Attribut einer WebTransport-Instanz aufgerufen, die einen ReadableStream-Wert zurückgibt. Jeder Block dieser ReadableStream ist wiederum ein WebTransportReceiveStream-Element, mit dem die vom Server gesendeten Uint8Array-Instanzen gelesen werden können.

async function readFrom(receiveStream) {
  const reader = receiveStream.readable.getReader();
  while (true) {
    const {done, value} = await reader.read();
    if (done) {
      break;
    }
    // value is a Uint8Array
    console.log(value);
  }
}

const rs = transport.incomingUnidirectionalStreams;
const reader = rs.getReader();
while (true) {
  const {done, value} = await reader.read();
  if (done) {
    break;
  }
  // value is an instance of WebTransportReceiveStream
  await readFrom(value);
}

Du kannst die Schließung eines Streams mithilfe des Promise closed des ReadableStreamDefaultReader erkennen. Wenn die zugrunde liegende HTTP/3-Verbindung mit dem FIN-Bit geschlossen wird, ist das Versprechen closed erfüllt, nachdem alle Daten gelesen wurden. Wenn die HTTP/3-Verbindung abrupt beendet wird (z. B. durch RESET\_STREAM), wird das Promise closed abgelehnt.

// Assume an active receiveStream
const reader = receiveStream.readable.getReader();
reader.closed.then(() => {
  console.log('The receiveStream closed gracefully.');
}).catch(() => {
  console.error('The receiveStream closed abruptly.');
});

WebTransportBidirectionalStream

Ein WebTransportBidirectionalStream kann entweder vom Server oder vom Client erstellt werden.

Webclients können einen Client mit der Methode createBidirectionalStream() einer WebTransport-Instanz erstellen, die ein Promise für ein WebTransportBidirectionalStream zurückgibt.

const stream = await transport.createBidirectionalStream();
// stream is a WebTransportBidirectionalStream
// stream.readable is a ReadableStream
// stream.writable is a WritableStream

Sie können auf eine WebTransportBidirectionalStream warten, die vom Server mit dem Attribut incomingBidirectionalStreams einer WebTransport-Instanz erstellt wurde, das einen ReadableStream zurückgibt. Jeder Block dieses ReadableStream ist wiederum ein WebTransportBidirectionalStream.

const rs = transport.incomingBidirectionalStreams;
const reader = rs.getReader();
while (true) {
  const {done, value} = await reader.read();
  if (done) {
    break;
  }
  // value is a WebTransportBidirectionalStream
  // value.readable is a ReadableStream
  // value.writable is a WritableStream
}

Ein WebTransportBidirectionalStream ist einfach eine Kombination aus WebTransportSendStream und WebTransportReceiveStream. Die Beispiele aus den beiden vorherigen Abschnitten zeigen ihre Verwendung.

Weitere Beispiele

Die Entwurfsspezifikation für WebTransport enthält eine Reihe zusätzlicher Inline-Beispiele sowie eine vollständige Dokumentation für alle Methoden und Eigenschaften.

WebTransport in den Chrome-Entwicklertools

Leider unterstützen die Chrome-Entwicklertools derzeit kein WebTransport. Sie können dieses Chrome-Problem markieren, um über Updates in der Benutzeroberfläche der Entwicklertools benachrichtigt zu werden.

Polyfill

Ein Polyfill (oder eher ein Ponyfill, das Funktionen als eigenständiges Modul bietet, das Sie verwenden können) namens webtransport-ponyfill-websocket, das einige Funktionen von WebTransport implementiert. Lesen Sie sich die Einschränkungen in der README des Projekts sorgfältig durch, um festzustellen, ob diese Lösung für Ihren Anwendungsfall geeignet ist.

Datenschutz und Sicherheit

Im entsprechenden Abschnitt des Spezifikationsentwurfs finden Sie eine verbindliche Anleitung.

Feedback

Das Chrome-Team möchte gern Ihre Meinung und Ihre Erfahrungen mit dieser API hören.

Feedback zum API-Design

Gibt es etwas an der API, das umständlich ist oder nicht wie erwartet funktioniert? Oder fehlen Teile, die Sie zur Umsetzung Ihrer Idee benötigen?

Sie können ein Problem im Web Transport GitHub-Repository melden oder Ihre Gedanken zu einem vorhandenen Problem hinzufügen.

Probleme bei der Implementierung?

Haben Sie einen Fehler bei der Implementierung in Chrome gefunden?

Melden Sie einen Fehler unter https://new.crbug.com. Geben Sie so viele Details wie möglich und eine einfache Anleitung zum Reproduzieren an.

Möchten Sie die API verwenden?

Ihre öffentliche Unterstützung hilft Chrome dabei, Funktionen zu priorisieren und anderen Browseranbietern zu zeigen, wie wichtig es ist, sie zu unterstützen.

Allgemeine Disussionen

Sie können die Google-Gruppe "web-transport-dev" für allgemeine Fragen oder Probleme nutzen, die zu keiner der anderen Kategorien passen.

Danksagungen

Dieser Artikel enthält Informationen aus WebTransport Explainer, Spezifikationsentwurf und zugehörigen Designdokumenten. Vielen Dank an die jeweiligen Autoren für die Bereitstellung dieser Grundlage.

Das Hero-Image in diesem Beitrag stammt von Robin Pierre auf Unsplash.