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 zu WebSockets und überträgt Daten zwischen Client und Server mithilfe von HTTP/3 Transport. WebTransport unterstützt mehrere Streams, unidirektionale Streams und die Zustellung außer der Reihenfolge. Sie ermöglicht zuverlässigen Transport über streams und unzuverlässigen Transport über UDP-ähnliche Datenpakete.
Konzepte und Verwendung
HTTP/3 ist seit 2018 in Bearbeitung. Es basiert auf Googles QUIC-Protokoll (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 einzelne Verbindung mehrere Ressourcen gleichzeitig streamen kann. Wenn jedoch eine einzelne Ressource ausfällt, werden alle anderen Ressourcen in dieser Verbindung aufgehalten, bis fehlende Pakete erneut übertragen werden. Mit QUIC ist nur die fehlerhafte Ressource betroffen.
- Schnellere Leistung
-
QUIC ist in vielerlei Hinsicht leistungsfähiger als TCP. QUIC kann Sicherheitsfunktionen selbst handhaben, anstatt die Verantwortung an andere Protokolle wie TLS zu übergeben — das bedeutet weniger Rundreisen. Und Streams bieten eine bessere Transporteffizienz als der ältere Paketmechanismus. Dies kann insbesondere in Netzwerken mit hoher Latenz einen deutlichen Unterschied machen.
- Bessere Netzwerkübergänge
-
QUIC verwendet eine eindeutige Verbindungs-ID, um die Quelle und das Ziel jeder Anfrage zu bearbeiten — um sicherzustellen, dass Pakete korrekt zugestellt werden. Diese ID kann zwischen verschiedenen Netzwerken beibehalten werden, was bedeutet, dass z. B. ein Download ohne Unterbrechung fortgesetzt werden kann, wenn Sie von Wi-Fi zu einem mobilen Netzwerk wechseln. HTTP/2 hingegen verwendet IP-Adressen als Identifikatoren, sodass Netzwerkübergänge problematisch sein können.
- Unzuverlässiger Transport
-
HTTP/3 unterstützt die unzuverlässige Datenübertragung über Datenpakete.
Die WebTransport API bietet einen Low-Level-Zugriff auf die bidirektionale Kommunikation über HTTP/3 und nutzt die oben genannten Vorteile, während sie sowohl zuverlässige als auch unzuverlässige Datenübertragung unterstützt.
Initiale Verbindung
Um eine Verbindung zu einem HTTP/3-Server herzustellen, übergeben Sie seine URL an den WebTransport()
-Konstruktor. Beachten Sie, dass das Schema HTTPS sein muss und die Portnummer explizit angegeben werden muss. Sobald das WebTransport.ready
-Versprechen erfüllt ist, können Sie die Verbindung nutzen.
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 durch WebTransport-Operationen zurückgegeben werden, sind vom Typ WebTransportError
und enthalten zusätzliche Daten über den Standard-Fehlersatz von 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 Datenpakete
"Unzuverlässig" bedeutet, dass die Übertragung von Daten nicht garantiert ist, ebenso wenig wie die Ankunft in einer bestimmten Reihenfolge. Dies ist in bestimmten Situationen in Ordnung und bietet eine sehr schnelle Zustellung. Zum Beispiel könnten Sie regelmäßige Statusaktualisierungen eines Spiels übertragen wollen, bei denen jede Nachricht die letzte überschreibt, die ankommt, und die Reihenfolge nicht wichtig ist.
Die 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 Datenpakete an den Server zu senden und zurückzuerhalten.
Die WebTransportDatagramDuplexStream.writable
-Eigenschaft gibt ein WritableStream
-Objekt zurück, zu dem Sie Daten mithilfe eines Writers 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, 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 Übertragung und Reihenfolge der Daten garantiert sind. Dies sorgt für langsamere Lieferung (allerdings schneller als bei WebSockets) und wird in Situationen benötigt, in denen Zuverlässigkeit und Reihenfolge wichtig sind (wie z. B. bei Chat-Anwendungen).
Bei Verwendung der zuverlässigen Ü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 Benutzeragenten zu öffnen, verwenden Sie die Methode WebTransport.createUnidirectionalStream()
, um eine Referenz auf einen WritableStream
zu erhalten. Von dort 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 dieser auf dem Client über die WebTransport.incomingUnidirectionalStreams
-Eigenschaft zugegriffen werden, die einen ReadableStream
von WebTransportReceiveStream
-Objekten zurückgibt. Diese können verwendet werden, um von dem Server gesendete Uint8Array
-Instanzen zu lesen.
In diesem Fall ist das Erste, was zu tun ist, eine Funktion einzurichten, um einen WebTransportReceiveStream
zu lesen. Diese Objekte erben von der ReadableStream
-Klasse und können daher auf dieselbe 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);
}
}
Rufen Sie als Nächstes WebTransport.incomingUnidirectionalStreams
auf und erhalten Sie eine Referenz auf den auf dem zurückgegebenen ReadableStream
verfügbaren Reader, und verwenden Sie dann den Reader, um die Daten vom Server zu lesen. Jeder Chunk 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 Benutzeragenten zu öffnen, verwenden Sie die Methode WebTransport.createBidirectionalStream()
, um eine Referenz auf einen WebTransportBidirectionalStream
zu erhalten.
Dieser enthält readable
- und writable
-Eigenschaften, die Referenzen auf WebTransportReceiveStream
- und WebTransportSendStream
-Instanzen zurückgeben, die zum Lesen vom und Schreiben an den Server verwendet werden können.
Hinweis: WebTransportBidirectionalStream
ähnelt dem WebTransportDatagramDuplexStream
, mit dem Unterschied, dass in diesem Interface die readable
- und writable
-Eigenschaften 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;
...
}
Der Lesevorgang aus dem WebTransportReceiveStream
kann dann wie folgt durchgeführt 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 in den WebTransportSendStream
kann so vorgenommen 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 übertragen und vom Client zu empfangen, kann darauf über die WebTransport.incomingBidirectionalStreams
-Eigenschaft zugegriffen werden, die einen ReadableStream
von WebTransportBidirectionalStream
-Objekten zurückgibt. Jedes kann verwendet werden, um Uint8Array
-Instanzen zu lesen und zu schreiben, wie oben gezeigt. Allerdings benötigen Sie, wie beim 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ät, um einem Benutzeragenten zu ermöglichen, sich mit einem HTTP/3-Server zu verbinden, 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 Datenpaketen zwischen Client und Server verwendet werden kann. Bietet Zugriff auf einen
ReadableStream
zum Lesen eingehender Datenpakete, einenWritableStream
zum Schreiben ausgehender Datenpakete sowie 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 durch den Client initiierte Abbruchvorgänge (zum Beispiel durch einen Aufruf von
WritableStream.abort()
) auftreten kann. WebTransportReceiveStream
-
Bietet Streaming-Funktionen für einen eingehenden unidirektionalen oder bidirektionalen
WebTransport
-Stream von WebTransport. 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 |
Browser-Kompatibilität
BCD tables only load in the browser