WebTransport API
Limited availability
This feature is not Baseline because it does not work in some of the most widely-used browsers.
Sicherer Kontext: Diese Funktion ist nur in sicheren Kontexten (HTTPS) in einigen oder allen unterstützenden Browsern verfügbar.
Hinweis: Diese Funktion ist in Web Workers verfügbar.
Die WebTransport API bietet ein modernes Update der WebSockets, indem sie Daten zwischen Client und Server über HTTP/3 Transport überträgt. WebTransport unterstützt mehrere Streams, unidirektionale Streams und außerordentliche Lieferung. Sie ermöglicht zuverlässigen Transport über Streams und unzuverlässigen Transport über UDP-ähnliche Datagramme.
Konzepte und Nutzung
HTTP/3 ist seit 2018 in Arbeit. Es basiert auf Googles QUIC-Protokoll (das selbst auf UDP basiert) und behebt mehrere Probleme im Zusammenhang mit dem klassischen TCP-Protokoll, auf dem HTTP und WebSockets basieren.
Dazu gehören:
- Head-of-line Blocking
-
HTTP/2 erlaubt Multiplexing, sodass eine einzelne Verbindung mehrere Ressourcen gleichzeitig streamen kann. Wenn jedoch eine einzelne Ressource scheitert, werden alle anderen Ressourcen auf dieser Verbindung zurückgehalten, bis fehlende Pakete neu übertragen werden. Bei QUIC wird nur die fehlgeschlagene Ressource betroffen.
- Schnellere Leistung
-
QUIC ist in vielerlei Hinsicht leistungsfähiger als TCP. QUIC kann Sicherheitsfunktionen eigenständig verwalten, anstatt die Verantwortung an andere Protokolle wie TLS zu delegieren – was weniger Rundreisen bedeutet. Und Streams bieten eine bessere Transporteffizienz als der ältere Paketmechanismus. Das kann einen wesentlichen Unterschied ausmachen, insbesondere in Hochlatenz-Netzwerken.
- Bessere Netzwerkübergänge
-
QUIC verwendet eine eindeutige Verbindungs-ID, um die Quelle und das Ziel jeder Anfrage zu verwalten — um sicherzustellen, dass Pakete korrekt zugestellt werden. Diese ID kann zwischen verschiedenen Netzwerken bestehen bleiben, was bedeutet, dass zum Beispiel ein Download ohne Unterbrechung fortgesetzt werden kann, wenn Sie von Wi-Fi zu einem mobilen Netzwerk wechseln. HTTP/2 hingegen verwendet IP-Adressen als Kennungen, sodass Netzwerkübergänge problematisch sein können.
- Unzuverlässiger Transport
-
HTTP/3 unterstützt unzuverlässige Datenübertragung über Datagramme.
Die WebTransport API bietet niedrigstufigen Zugriff auf die bidirektionale Kommunikation über HTTP/3, nutzt die vorgenannten Vorteile und unterstützt sowohl zuverlässige als auch unzuverlässige Datenübertragung.
Initiale Verbindung
Um eine Verbindung zu einem HTTP/3-Server herzustellen, übergeben Sie dessen URL dem WebTransport()
-Konstruktor. Beachten Sie, dass das Schema HTTPS sein muss und die Portnummer ausdrücklich angegeben werden muss. Sobald das WebTransport.ready
-Versprechen erfüllt ist, können Sie die Verbindung verwenden.
Beachten Sie auch, dass Sie auf das Schließen der Verbindung reagieren können, indem Sie warten, bis das WebTransport.closed
-Versprechen erfüllt ist. Fehler, die von WebTransport-Operationen zurückgegeben werden, sind vom Typ WebTransportError
und enthalten zusätzliche Daten über den Standardsatz von DOMException
hinaus.
const url = "https://example.com:4999/wt";
async function initTransport(url) {
// Initialize transport connection
const transport = new WebTransport(url);
// The connection can be used once ready fulfills
await transport.ready;
// ...
}
// ...
async function closeTransport(transport) {
// Respond to connection closing
try {
await transport.closed;
console.log(`The HTTP/3 connection to ${url} closed gracefully.`);
} catch (error) {
console.error(`The HTTP/3 connection to ${url} closed due to ${error}.`);
}
}
Unzuverlässige Übertragung über Datagramme
"Unzuverlässig" bedeutet, dass die Übertragung von Daten nicht garantiert ist, noch deren Ankunft in einer bestimmten Reihenfolge. Dies ist in einigen Situationen in Ordnung und ermöglicht eine sehr schnelle Lieferung. Zum Beispiel könnte man regelmäßige Spielstatus-Updates übertragen wollen, bei denen jede Nachricht die letzte eingetroffene Nachricht ersetzt und die Reihenfolge keine Rolle spielt.
Die unzuverlässige Datenübertragung wird über die WebTransport.datagrams
-Eigenschaft gehandhabt — diese gibt ein WebTransportDatagramDuplexStream
-Objekt zurück, das alles enthält, was zum Senden von Datagrammen an den Server und deren Empfang zurück benötigt wird.
Die WebTransportDatagramDuplexStream.writable
-Eigenschaft gibt ein WritableStream
-Objekt zurück, zu dem Sie Daten über einen Writer zur Übertragung an den Server schreiben können:
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);
Die WebTransportDatagramDuplexStream.readable
-Eigenschaft gibt ein ReadableStream
-Objekt zurück, mit dem Sie Daten vom Server empfangen können:
async function readData() {
const reader = transport.datagrams.readable.getReader();
while (true) {
const { value, done } = await reader.read();
if (done) {
break;
}
// value is a Uint8Array.
console.log(value);
}
}
Zuverlässige Übertragung über Streams
"Zuverlässig" bedeutet, dass Übertragung und Reihenfolge der Daten garantiert sind. Dies sorgt für eine langsamere Lieferung (wenn auch schneller als bei WebSockets) und wird in Situationen benötigt, in denen Zuverlässigkeit und Reihenfolge wichtig sind (zum Beispiel bei Chat-Anwendungen).
Bei der Verwendung zuverlässiger Übertragung über Streams können Sie auch die relative Priorität verschiedener Streams über denselben Transport einstellen.
Unidirektionale Übertragung
Um einen unidirektionalen Stream von einem User-Agent zu öffnen, verwenden Sie die Methode WebTransport.createUnidirectionalStream()
, um eine Referenz zu einem WritableStream
zu erhalten. Von diesem können Sie einen Writer erhalten, um Daten in den Stream zu schreiben und an den Server zu senden.
async function writeData() {
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}`);
}
}
Beachten Sie auch die Verwendung der Methode WritableStreamDefaultWriter.close()
, um die zugehörige HTTP/3-Verbindung zu schließen, sobald alle Daten gesendet wurden.
Wenn der Server einen unidirektionalen Stream öffnet, um Daten an den Client zu übertragen, kann darauf auf der Clientseite über die WebTransport.incomingUnidirectionalStreams
-Eigenschaft zugegriffen werden, die einen ReadableStream
mit WebTransportReceiveStream
-Objekten zurückgibt. Diese können verwendet werden, um von dem Server gesendete Uint8Array
-Instanzen zu lesen.
In diesem Fall ist es zunächst erforderlich, eine Funktion zum Lesen eines WebTransportReceiveStream
einzurichten. Diese Objekte erben von der ReadableStream
-Klasse, so dass sie auf die gleiche Weise verwendet werden können:
async function readData(receiveStream) {
const reader = receiveStream.getReader();
while (true) {
const { done, value } = await reader.read();
if (done) {
break;
}
// value is a Uint8Array
console.log(value);
}
}
Als Nächstes rufen Sie WebTransport.incomingUnidirectionalStreams
auf und erhalten eine Referenz zum verfügbaren Leser auf dem vom ReadableStream
zurückgegebenen Objekt, und verwenden dann den Leser, um die Daten vom Server zu lesen. Jedes Segment ist ein WebTransportReceiveStream
, und wir verwenden das zuvor eingerichtete readFrom()
, um sie zu lesen:
async function receiveUnidirectional() {
const uds = transport.incomingUnidirectionalStreams;
const reader = uds.getReader();
while (true) {
const { done, value } = await reader.read();
if (done) {
break;
}
// value is an instance of WebTransportReceiveStream
await readData(value);
}
}
Bidirektionale Übertragung
Um einen bidirektionalen Stream von einem User-Agent zu öffnen, verwenden Sie die Methode WebTransport.createBidirectionalStream()
, um eine Referenz zu einem WebTransportBidirectionalStream
zu erhalten. Dieser enthält readable
und writable
Eigenschaften, die Referenzen zu WebTransportReceiveStream
und WebTransportSendStream
Instanzen zurückgeben, mit denen Sie vom Server lesen und auf den Server schreiben können.
Hinweis: WebTransportBidirectionalStream
ist ähnlich wie WebTransportDatagramDuplexStream
, außer dass die readable
und writable
Eigenschaften in dieser Schnittstelle jeweils ReadableStream
und WritableStream
sind.
async function setUpBidirectional() {
const stream = await transport.createBidirectionalStream();
// stream is a WebTransportBidirectionalStream
// stream.readable is a WebTransportReceiveStream
const readable = stream.readable;
// stream.writable is a WebTransportSendStream
const writable = stream.writable;
// …
}
Das Lesen aus dem WebTransportReceiveStream
kann dann wie folgt erfolgen:
async function readData(readable) {
const reader = readable.getReader();
while (true) {
const { value, done } = await reader.read();
if (done) {
break;
}
// value is a Uint8Array.
console.log(value);
}
}
Und das Schreiben in den WebTransportSendStream
kann so gemacht werden:
async function writeData(writable) {
const writer = writable.getWriter();
const data1 = new Uint8Array([65, 66, 67]);
const data2 = new Uint8Array([68, 69, 70]);
writer.write(data1);
writer.write(data2);
}
Wenn der Server einen bidirektionalen Stream öffnet, um Daten zu senden und vom Client zu empfangen, kann darauf über die WebTransport.incomingBidirectionalStreams
-Eigenschaft zugegriffen werden, die einen ReadableStream
von WebTransportBidirectionalStream
-Objekten zurückgibt. Jedes davon kann wie oben gezeigt verwendet werden, um Uint8Array
-Instanzen zu lesen und zu schreiben. Allerdings benötigen Sie, wie im Fall des unidirektionalen Beispiels, eine anfängliche Funktion, um den bidirektionalen Stream überhaupt erst lesen zu können:
async function receiveBidirectional() {
const bds = transport.incomingBidirectionalStreams;
const reader = bds.getReader();
while (true) {
const { done, value } = await reader.read();
if (done) {
break;
}
// value is an instance of WebTransportBidirectionalStream
await readData(value.readable);
await writeData(value.writable);
}
}
Schnittstellen
WebTransport
-
Bietet Funktionalität, um einem User-Agent zu ermöglichen, eine Verbindung zu einem HTTP/3-Server herzustellen, zuverlässigen und unzuverlässigen Transport in eine oder beide Richtungen zu initiieren und die Verbindung zu schließen, sobald sie nicht mehr benötigt wird.
WebTransportBidirectionalStream
-
Stellt einen vom Server oder Client erstellten bidirektionalen Stream dar, der für zuverlässigen Transport verwendet werden kann. Bietet Zugriff auf einen
ReadableStream
zum Lesen eingehender Daten und einenWritableStream
zum Schreiben ausgehender Daten. WebTransportDatagramDuplexStream
-
Stellt einen Duplex-Stream dar, der für unzuverlässigen Transport von Datagrammen zwischen Client und Server verwendet werden kann. Bietet Zugriff auf einen
ReadableStream
zum Lesen eingehender Datagramme, einenWritableStream
zum Schreiben ausgehender Datagramme und verschiedene Einstellungen und Statistiken im Zusammenhang mit dem Stream. WebTransportError
-
Stellt einen Fehler im Zusammenhang mit der WebTransport API dar, der durch Serverfehler, Netzwerkverbindungsprobleme oder vom Client initiierte Abbruchoperationen (z. B. durch einen Aufruf von
WritableStream.abort()
) entstehen kann. WebTransportReceiveStream
-
Bietet Streaming-Funktionen für einen eingehenden unidirektionalen oder bidirektionalen
WebTransport
-Stream. WebTransportSendStream
-
Bietet Streaming-Funktionen für einen ausgehenden unidirektionalen oder bidirektionalen
WebTransport
-Stream.
Beispiele
Für vollständige Beispiele siehe:
Spezifikationen
Specification |
---|
WebTransport # web-transport |