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 eine moderne Aktualisierung für WebSockets und überträgt Daten zwischen Client und Server mit HTTP/3 Transport. WebTransport unterstützt mehrere Streams, unidirektionale Streams und die Übertragung in ungeordneter Reihenfolge. Es ermöglicht zuverlässigen Transport über Streams und unzuverlässigen Transport über UDP-ähnliche Datagramme.
Konzepte und Nutzung
HTTP/3 ist seit 2018 in Entwicklung. Es basiert auf dem QUIC-Protokoll von Google (das seinerseits auf UDP basiert) und behebt mehrere Probleme des klassischen TCP-Protokolls, auf dem HTTP und WebSockets basieren.
Diese beinhalten:
- Head-of-line Blocking
-
HTTP/2 ermöglicht Multiplexing, sodass eine einzige Verbindung mehrere Ressourcen gleichzeitig übertragen kann. Wenn jedoch eine einzelne Ressource fehlschlägt, werden alle anderen Ressourcen auf dieser Verbindung aufgehalten, bis alle fehlenden Pakete erneut übertragen werden. Bei QUIC ist nur die fehlerhafte Ressource betroffen.
- Schnellere Leistung
-
QUIC ist in vielerlei Hinsicht leistungsfähiger als TCP. QUIC kann Sicherheitsfunktionen eigenständig handhaben, anstatt die Verantwortung an andere Protokolle wie TLS zu übergeben, was weniger Round-Trips bedeutet. Und Streams bieten eine bessere Transporteffizienz als der ältere Paketmechanismus, was besonders in Netzwerken mit hoher Latenz einen signifikanten Unterschied machen kann.
- Bessere Netzwerkübergänge
-
QUIC verwendet eine eindeutige Verbindungs-ID, um die Quelle und das Ziel jeder Anfrage zu handhaben und sicherzustellen, dass Pakete korrekt zugestellt werden. Diese ID kann zwischen verschiedenen Netzwerken bestehen bleiben, wodurch beispielsweise ein Download weiterlaufen kann, ohne unterbrochen zu werden, wenn Sie von Wi-Fi zu einem Mobilfunknetz wechseln. HTTP/2 hingegen verwendet IP-Adressen als Identifikatoren, 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 einen Low-Level-Zugang zur bidirektionalen Kommunikation über HTTP/3. Sie nutzt die oben genannten Vorteile und unterstützt sowohl zuverlässige als auch unzuverlässige Datenübertragung.
Erste Verbindung
Um eine Verbindung zu einem HTTP/3-Server herzustellen, übergeben Sie dessen URL an den WebTransport()
-Konstruktor. Beachten Sie, dass das Schema HTTPS sein muss und die Portnummer explizit angegeben werden muss. Sobald das WebTransport.ready
-Promise erfüllt ist, können Sie die Verbindung nutzen.
Außerdem können Sie auf das Schließen der Verbindung reagieren, indem Sie warten, bis das WebTransport.closed
-Promise erfüllt ist. Fehler, die von WebTransport-Operationen zurückgegeben werden, sind vom Typ WebTransportError
und enthalten zusätzliche Daten neben dem Standardsatz an DOMException
.
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 das Eintreffen in einer bestimmten Reihenfolge. Dies ist in einigen Situationen in Ordnung und ermöglicht sehr schnelle Zustellung. Beispielsweise möchten Sie möglicherweise regelmäßige Spielstatus-Updates übertragen, bei denen jede Nachricht die zuletzt eingetroffene überschreibt und die Reihenfolge unwichtig ist.
Unzuverlässige Datenübertragung wird über die WebTransport.datagrams
-Eigenschaft gehandhabt – diese gibt ein WebTransportDatagramDuplexStream
-Objekt zurück, das alles enthält, was Sie benötigen, um Datagramme an den Server zu senden und sie zurückzuerhalten.
Die WebTransportDatagramDuplexStream.writable
-Eigenschaft gibt ein WritableStream
-Objekt zurück, in das Sie mit einem Writer Daten für die Übertragung zum 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, das Sie verwenden können, um Daten vom Server zu empfangen:
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 die Übertragung und Reihenfolge der Daten garantiert ist. Dies führt zu langsamerer Zustellung (wenn auch schneller als mit WebSockets) und ist in Situationen erforderlich, in denen Zuverlässigkeit und Reihenfolge wichtig sind (beispielsweise in Chat-Anwendungen).
Bei zuverlässiger Übertragung über Streams können Sie auch die relative Priorität verschiedener Streams über denselben Transportkanal festlegen.
Unidirektionale Übertragung
Um einen unidirektionalen Stream von einem Benutzeragenten zu öffnen, verwenden Sie die Methode WebTransport.createUnidirectionalStream()
, um eine Referenz zu einem WritableStream
zu erhalten. Damit 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 der Client darauf über die WebTransport.incomingUnidirectionalStreams
-Eigenschaft zugreifen, die einen ReadableStream
von WebTransportReceiveStream
-Objekten zurückgibt. Diese können verwendet werden, um Uint8Array
-Instanzen zu lesen, die vom Server gesendet wurden.
In diesem Fall ist der erste Schritt, eine Funktion zu erstellen, um einen WebTransportReceiveStream
zu lesen. Diese Objekte erben von der ReadableStream
-Klasse und können auf die gleiche Weise verwendet werden:
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 Reader des ReadableStream
, den es zurückgibt. Verwenden Sie dann den Reader, um die Daten vom Server zu lesen. Jeder Chunk ist ein WebTransportReceiveStream
, und wir verwenden die zuvor eingerichtete readFrom()
-Funktion, 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 Benutzeragenten zu öffnen, verwenden Sie die Methode WebTransport.createBidirectionalStream()
, um eine Referenz zu einem WebTransportBidirectionalStream
zu erhalten.
Dieses enthält die Eigenschaften readable
und writable
, die Referenzen zu WebTransportReceiveStream
- und WebTransportSendStream
-Instanzen zurückgeben, die zum Lesen und Schreiben zum Server verwendet werden können.
Hinweis:>WebTransportBidirectionalStream
ähnelt WebTransportDatagramDuplexStream
, außer dass in dieser Schnittstelle die Eigenschaften readable
und writable
ReadableStream
respektive 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 vom WebTransportReceiveStream
kann dann wie folgt vorgenommen werden:
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 auf den WebTransportSendStream
kann folgendermaßen erfolgen:
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 übertragen und vom Client zu empfangen, kann darauf über die WebTransport.incomingBidirectionalStreams
-Eigenschaft zugegriffen werden, die einen ReadableStream
von WebTransportBidirectionalStream
-Objekten zurückgibt. Jeder von ihnen kann verwendet werden, um Uint8Array
-Instanzen wie oben gezeigt zu lesen und zu schreiben. Allerdings benötigen Sie, wie im unidirektionalen Beispiel, eine Anfangsfunktion, um den bidirektionalen Stream überhaupt zu lesen:
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äten für einen Benutzeragenten, um 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, wenn sie nicht mehr benötigt wird.
WebTransportBidirectionalStream
-
Repräsentiert einen bidirektionalen Stream, der von einem Server oder Client erstellt wurde und für den zuverlässigen Transport verwendet werden kann. Bietet Zugang zu einem
ReadableStream
zum Lesen eingehender Daten und einemWritableStream
zum Schreiben ausgehender Daten. WebTransportDatagramDuplexStream
-
Repräsentiert einen Duplex-Stream, der für den unzuverlässigen Transport von Datagrammen zwischen Client und Server verwendet werden kann. Bietet Zugang zu einem
ReadableStream
zum Lesen eingehender Datagramme, einemWritableStream
zum Schreiben ausgehender Datagramme sowie verschiedenen Einstellungen und Statistiken im Zusammenhang mit dem Stream. WebTransportError
-
Repräsentiert einen Fehler im Zusammenhang mit der WebTransport API, der durch Serverfehler, Netzwerkverbindungsprobleme oder clientinitiierte Abbruchvorgänge (z.B. durch einen Aufruf von
WritableStream.abort()
) auftreten kann. WebTransportReceiveStream
-
Bietet Streaming-Funktionen für einen eingehenden WebTransport-uni- oder bidirektionalen
WebTransport
-Stream. WebTransportSendStream
-
Bietet Streaming-Funktionen für einen ausgehenden WebTransport-uni- oder bidirektionalen
WebTransport
-Stream.
Beispiele
Für vollständige Beispiele siehe:
Spezifikationen
Specification |
---|
WebTransport # web-transport |