WebTransport gebruiken

WebTransport is een API die bidirectionele client-server-berichten met lage latentie biedt. Lees meer over de gebruiksscenario's en hoe u feedback kunt geven over de toekomst van de implementatie.

Achtergrond

Wat is WebTransport?

WebTransport is een web-API die het HTTP/3 -protocol gebruikt als bidirectioneel transport. Het is bedoeld voor tweerichtingscommunicatie tussen een webclient en een HTTP/3-server. Het ondersteunt het verzenden van gegevens zowel op onbetrouwbare wijze via de datagram-API's , als op betrouwbare wijze via de streams-API's .

Datagrammen zijn ideaal voor het verzenden en ontvangen van gegevens waarvoor geen sterke leveringsgaranties nodig zijn. Individuele gegevenspakketten worden in omvang beperkt door de maximale transmissie-eenheid (MTU) van de onderliggende verbinding, en kunnen al dan niet met succes worden verzonden, en als ze worden overgedragen, kunnen ze in een willekeurige volgorde aankomen. Deze kenmerken maken de datagram-API's ideaal voor gegevensoverdracht met lage latentie en de beste inspanningen. U kunt datagrammen beschouwen als UDP-berichten (User Datagram Protocol) , maar dan gecodeerd en met congestiecontrole.

De streams-API's zorgen daarentegen voor een betrouwbare , geordende gegevensoverdracht. Ze zijn zeer geschikt voor scenario's waarin u een of meer stromen bestelde gegevens moet verzenden of ontvangen. Het gebruik van meerdere WebTransport-streams is analoog aan het tot stand brengen van meerdere TCP -verbindingen, maar omdat HTTP/3 het lichtere QUIC- protocol onder de motorkap gebruikt, kunnen ze worden geopend en gesloten zonder al te veel overhead.

Gebruiksgevallen

Dit is een kleine lijst met mogelijke manieren waarop ontwikkelaars WebTransport kunnen gebruiken.

  • Het verzenden van de spelstatus met regelmatige tussenpozen en minimale latentie naar een server via kleine, onbetrouwbare berichten die niet in orde zijn.
  • Het ontvangen van mediastreams die vanaf een server worden gepusht met minimale latentie, onafhankelijk van andere datastromen.
  • Het ontvangen van meldingen die vanaf een server worden gepusht terwijl een webpagina geopend is.

We willen graag meer weten over hoe u WebTransport wilt gebruiken.

Browser-ondersteuning

Browserondersteuning

  • Chroom: 97.
  • Rand: 97.
  • Firefox: 114.
  • Safari: niet ondersteund.

Bron

Zoals bij alle functies die geen universele browserondersteuning hebben, is defensief coderen via functiedetectie een best practice.

Huidige status

Stap Status
1. Maak een uitleg Compleet
2. Maak een eerste ontwerp van specificatie Compleet
3. Verzamel feedback en herhaal het ontwerp Compleet
4. Oorsprongsproces Compleet
5. Lancering Chroom 97

De relatie van WebTransport met andere technologieën

Is WebTransport een vervanging voor WebSockets?

Misschien. Er zijn gebruiksscenario's waarbij WebSockets of WebTransport geldige communicatieprotocollen kunnen zijn om te gebruiken.

WebSockets-communicatie is gemodelleerd rond een enkele, betrouwbare, geordende stroom berichten, wat prima is voor sommige soorten communicatiebehoeften. Als u deze kenmerken nodig heeft, kunnen de streams-API's van WebTransport deze ook bieden. Ter vergelijking: de datagram-API's van WebTransport bieden levering met lage latentie, zonder garanties over betrouwbaarheid of bestelling, en zijn dus geen directe vervanging voor WebSockets.

Het gebruik van WebTransport, via de datagram-API's of via meerdere gelijktijdige Streams API-instanties, betekent dat u zich geen zorgen hoeft te maken over head-of-line-blokkering , wat een probleem kan zijn bij WebSockets. Bovendien zijn er prestatievoordelen bij het tot stand brengen van nieuwe verbindingen, omdat de onderliggende QUIC-handshake sneller is dan het opstarten van TCP via TLS.

WebTransport maakt deel uit van een nieuwe conceptspecificatie en als zodanig is het WebSocket-ecosysteem rond client- en serverbibliotheken momenteel veel robuuster. Als je iets nodig hebt dat "out of the box" werkt met algemene serverconfiguraties en met brede webclientondersteuning, dan is WebSockets tegenwoordig een betere keuze.

Is WebTransport hetzelfde als een UDP Socket API?

Nee. WebTransport is geen UDP Socket API . Terwijl WebTransport HTTP/3 gebruikt, dat op zijn beurt UDP "onder de motorkap" gebruikt, heeft WebTransport eisen op het gebied van encryptie en congestiecontrole, waardoor het meer is dan een standaard UDP Socket API.

Is WebTransport een alternatief voor WebRTC-datakanalen?

Ja, voor client-serververbindingen. WebTransport deelt veel van dezelfde eigenschappen als WebRTC-datakanalen , hoewel de onderliggende protocollen verschillend zijn.

Over het algemeen vereist het runnen van een HTTP/3-compatibele server minder installatie en configuratie dan het onderhouden van een WebRTC-server, wat inhoudt dat je meerdere protocollen ( ICE , DTLS en SCTP ) moet begrijpen om een ​​werkend transport te krijgen. WebRTC brengt nog veel meer bewegende stukken met zich mee die kunnen leiden tot mislukte client/server-onderhandelingen.

De WebTransport API is ontworpen met de gebruiksscenario's van webontwikkelaars in gedachten en zou meer moeten aanvoelen als het schrijven van moderne webplatformcode dan het gebruik van de datakanaalinterfaces van WebRTC. In tegenstelling tot WebRTC wordt WebTransport ondersteund binnen Web Workers , waardoor u client-server-communicatie kunt uitvoeren onafhankelijk van een bepaalde HTML-pagina. Omdat WebTransport een Streams -compatibele interface biedt, ondersteunt het optimalisaties rond tegendruk .

Als u echter al een werkende WebRTC client/server-installatie heeft waar u tevreden mee bent, biedt het overstappen naar WebTransport wellicht niet veel voordelen.

Probeer het eens

De beste manier om met WebTransport te experimenteren is door een compatibele HTTP/3-server op te starten. U kunt deze pagina vervolgens gebruiken met een eenvoudige JavaScript-client om de client/server-communicatie uit te proberen.

Bovendien is er een door de gemeenschap onderhouden echoserver beschikbaar op webtransport.day .

Met behulp van de API

WebTransport is ontworpen bovenop moderne webplatformprimitieven, zoals de Streams API . Het leunt zwaar op beloftes en werkt goed met async en await .

De huidige WebTransport-implementatie in Chromium ondersteunt drie verschillende soorten verkeer: datagrammen, evenals zowel unidirectionele als bidirectionele stromen.

Verbinding maken met een server

U kunt verbinding maken met een HTTP/3-server door een WebTransport instantie te maken. Het schema van de URL moet https zijn. U moet het poortnummer expliciet opgeven.

U moet de ready gebruiken om te wachten tot de verbinding tot stand is gebracht. Deze belofte zal pas worden nagekomen als de installatie is voltooid, en zal worden afgewezen als de verbinding mislukt in de QUIC/TLS-fase.

De closed belofte wordt vervuld wanneer de verbinding normaal wordt gesloten, en wordt afgewezen als de sluiting onverwacht was.

Als de server de verbinding afwijst vanwege een clientindicatiefout (bijvoorbeeld het pad van de URL is ongeldig), dan zorgt dat ervoor dat closed wordt afgewezen, terwijl ready onopgelost blijft.

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-API's

Zodra u een WebTransport-instantie hebt die is verbonden met een server, kunt u deze gebruiken voor het verzenden en ontvangen van afzonderlijke gegevensbits, ook wel datagrammen genoemd.

De writeable getter retourneert een WritableStream , die een webclient kan gebruiken om gegevens naar de server te verzenden. De readable getter retourneert een ReadableStream , waardoor u naar gegevens van de server kunt luisteren. Beide stromen zijn inherent onbetrouwbaar, dus het is mogelijk dat de gegevens die u schrijft niet door de server worden ontvangen, en omgekeerd.

Beide typen streams gebruiken Uint8Array instanties voor gegevensoverdracht.

// 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);
}

Streamt API's

Zodra u verbinding heeft gemaakt met de server, kunt u WebTransport ook gebruiken om gegevens te verzenden en ontvangen via de Streams API's.

Elk deel van alle streams is een Uint8Array . In tegenstelling tot de Datagram API’s zijn deze streams betrouwbaar. Maar elke stream is onafhankelijk, dus de gegevensvolgorde tussen streams is niet gegarandeerd.

WebTransportSendStream

Een WebTransportSendStream wordt gemaakt door de webclient met behulp van de createUnidirectionalStream() -methode van een WebTransport instantie, die een belofte retourneert voor de WebTransportSendStream .

Gebruik de close() methode van de WritableStreamDefaultWriter om de bijbehorende HTTP/3-verbinding te sluiten. De browser probeert alle openstaande gegevens te verzenden voordat de bijbehorende verbinding daadwerkelijk wordt verbroken.

// 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}`);
}

Gebruik op dezelfde manier de methode abort() van de WritableStreamDefaultWriter om een RESET\_STREAM naar de server te sturen. Wanneer abort() gebruikt, kan de browser alle openstaande gegevens die nog niet zijn verzonden, verwijderen.

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

Een WebTransportReceiveStream wordt geïnitieerd door de server. Het verkrijgen van een WebTransportReceiveStream is een proces in twee stappen voor een webclient. Ten eerste roept het het incomingUnidirectionalStreams -attribuut van een WebTransport instantie aan, dat een ReadableStream retourneert. Elk deel van die ReadableStream is op zijn beurt een WebTransportReceiveStream die kan worden gebruikt om Uint8Array instanties te lezen die door de server zijn verzonden.

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);
}

U kunt het sluiten van streams detecteren met behulp van de closed belofte van ReadableStreamDefaultReader . Wanneer de onderliggende HTTP/3-verbinding wordt gesloten met de FIN-bit , wordt de closed belofte vervuld nadat alle gegevens zijn gelezen. Wanneer de HTTP/3-verbinding abrupt wordt verbroken (bijvoorbeeld door RESET\_STREAM ), wordt de closed belofte afgewezen.

// 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.');
});

WebTransportBidirectioneleStream

Een WebTransportBidirectionalStream kan door de server of door de client worden gemaakt.

Webclients kunnen er een maken met behulp van de createBidirectionalStream() -methode van een WebTransport instantie, die een belofte retourneert voor een WebTransportBidirectionalStream .

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

U kunt luisteren naar een WebTransportBidirectionalStream die door de server is gemaakt met het incomingBidirectionalStreams -kenmerk van een WebTransport instantie, die een ReadableStream retourneert. Elk deel van die ReadableStream is op zijn beurt een 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
}

Een WebTransportBidirectionalStream is slechts een combinatie van een WebTransportSendStream en WebTransportReceiveStream . In de voorbeelden uit de vorige twee secties wordt uitgelegd hoe u ze allemaal kunt gebruiken.

Meer voorbeelden

De conceptspecificatie van WebTransport bevat een aantal aanvullende inline-voorbeelden, samen met volledige documentatie voor alle methoden en eigenschappen.

WebTransport in DevTools van Chrome

Helaas ondersteunen de DevTools van Chrome momenteel geen WebTransport. U kunt dit Chrome-probleem een ​​ster geven om op de hoogte te blijven van updates in de DevTools-interface.

Polyvulling

Er is een polyfill (of beter gezegd ponyfill die functionaliteit biedt als een zelfstandige module die u kunt gebruiken) genaamd webtransport-ponyfill-websocket die enkele van de functies van WebTransport implementeert, beschikbaar. Lees zorgvuldig de beperkingen in de README van het project om te bepalen of deze oplossing voor uw gebruiksscenario kan werken.

Privacy- en veiligheidsoverwegingen

Zie het overeenkomstige gedeelte van de conceptspecificatie voor gezaghebbende richtlijnen.

Feedback

Het Chrome-team wil graag uw mening en ervaringen horen met het gebruik van deze API.

Feedback over het API-ontwerp

Is er iets aan de API dat lastig is of niet werkt zoals verwacht? Of ontbreken er stukjes die je nodig hebt om je idee te verwezenlijken?

Dien een probleem in op de Web Transport GitHub-repository of voeg uw mening toe aan een bestaand probleem.

Probleem met de implementatie?

Heeft u een bug gevonden in de implementatie van Chrome?

Dien een bug in op https://new.crbug.com . Voeg zoveel mogelijk details toe, samen met eenvoudige instructies voor reproductie.

Bent u van plan de API te gebruiken?

Uw publieke steun helpt Chrome prioriteit te geven aan functies en laat andere browserleveranciers zien hoe belangrijk het is om deze te ondersteunen.

Algemene discussie

Voor algemene vragen of problemen die niet in een van de andere categorieën passen, kunt u de web-transport-dev Google Group gebruiken.

Dankbetuigingen

Dit artikel bevat informatie uit de WebTransport Exploreer , conceptspecificaties en gerelateerde ontwerpdocumenten . Dank aan de respectievelijke auteurs voor het verschaffen van die basis.

De heldenafbeelding op dit bericht is van Robin Pierre op Unsplash.