Dev

Experimentando con WebTransport

WebTransport es una nueva API que ofrece mensajería cliente-servidor bidireccional de baja latencia. Obtenga más información sobre sus casos de uso y cómo dar comentarios sobre el futuro de la implementación.


Actualizado

Precaución: Esta propuesta ha sufrido cambios importantes desde el inicio del Ensayo de Origen. A partir de Chrome 87, WebTransport ha reemplazado a QuicTransport como la interfaz de nivel superior con la que interactúan los desarrolladores.

Como resultado, parte de la información y todo el código de muestra de este artículo está desactualizado. Para conocer las últimas novedades sobre esta propuesta en evolución, consulte el
borrador del editor de WebTransport. Incluye un Ejemplos sección con fragmentos de código actualizados.

Una vez que la propuesta se estabilice, actualizaremos este artículo y los ejemplos de código asociados con información actualizada.

Antecedentes

¿Qué es QuicTransport?

QuicTransport es una API web que utiliza QUIC protocolo en un transporte bidireccional, no HTTP. Está diseñado para comunicaciones bidireccionales entre un cliente web y un servidor QUIC. Admite el envío de datos de manera poco confiable a través de sus API de datagramas y de manera confiable a través de sus API de transmisión.

Datagramas son ideales para enviar y recibir datos que no necesitan fuertes garantías de entrega. Los paquetes individuales de datos están limitados en tamaño por el unidad de transmisión máxima (MTU) de la conexión subyacente, y pueden o no transmitirse con éxito, y si se transfieren, pueden llegar en un orden arbitrario. Estas características hacen que las API de datagramas sean ideales para la transmisión de datos de baja latencia y el mejor esfuerzo. Puedes pensar en los datagramas como protocolo de datagramas de usuario (UDP) mensajes, pero cifrados y controlados por congestión.

Las API de streams, por el contrario, proporcionan de confianza, transferencia de datos ordenada. Son muy adecuado a escenarios en los que necesita enviar o recibir uno o más flujos de datos ordenados. El uso de múltiples flujos QUIC es análogo a establecer múltiples TCP conexiones, pero los flujos QUIC son livianos y se pueden abrir y cerrar sin mucha sobrecarga.

¿Qué es WebTransport?

QuicTransport es una parte del mayor Propuesta de WebTransport. WebTransport es una colección de API para enviar y recibir datos entre un cliente web y un servidor. QuicTransport es la interfaz para utilizar el protocolo QUIC en el contexto de las comunicaciones WebTransport bidireccionales.

Chrome está implementando la parte QuicTransport de WebTransport primero, antes que cualquiera de las otras interfaces propuestas. El equipo de Chrome tomó la decisión de comenzar con QuicTransport después de hablar con los desarrolladores web sobre sus casos de uso. Esperamos solicitar retroalimentación temprana sobre el esfuerzo general de WebTransport basado en las experiencias de los desarrolladores con QuicTransport.

Casos de uso

Esta es una pequeña lista de las posibles formas en que los desarrolladores pueden usar QuicTransport.

  • Enviar el estado del juego a intervalos regulares con una latencia mínima a un servidor a través de mensajes pequeños, poco confiables y fuera de orden.
  • Recibir transmisiones de medios enviadas desde un servidor con latencia mínima, independientemente de otras transmisiones de datos.
  • Recibir notificaciones enviadas desde un servidor mientras una página web está abierta.

Como parte del proceso de prueba de origen, estamos interesados ​​en conocer más sobre cómo planea usar QuicTransport.

Estado actual

Paso Estado
1. Crea un explicador Completar
2. Crear borrador inicial de especificación Completar
3. Recopile comentarios y repita el diseño En progreso
4. Prueba de origen En progreso
5. Lanzamiento No empezado

Relación de QuicTransport con otras tecnologías

¿QuicTransport es un reemplazo de WebSockets?

Tal vez. Hay casos de uso en los que WebSockets o QuicTransport pueden ser protocolos de comunicación válidos para usar.

Las comunicaciones de WebSockets se modelan en torno a un flujo de mensajes único, confiable y ordenado, lo cual está bien para algunos tipos de necesidades de comunicación. Si necesita esas características, las API de streams de QuicTransport también pueden proporcionarlas. En comparación, las API de datagramas de QuicTransport brindan una entrega de baja latencia, sin garantías de confiabilidad o pedidos, por lo que no son un reemplazo directo de WebSockets.

El uso de QuicTransport, a través de las API de datagramas o mediante múltiples instancias de API de Streams simultáneas, significa que no tiene que preocuparse por bloqueo de cabecera de línea, que puede ser un problema con WebSockets. Además, existen beneficios de rendimiento al establecer nuevas conexiones, ya que Apretón de manos rápido es más rápido que iniciar TCP sobre TLS.

QuicTransport es parte de un nuevo borrador de especificación y, como tal, el ecosistema WebSocket en torno a las bibliotecas de cliente y servidor es actualmente mucho más sólido. Si necesita algo que funcione “fuera de la caja” con configuraciones de servidor comunes y con un amplio soporte de cliente web, WebSockets es una mejor opción hoy en día.

¿QuicTransport es lo mismo que una API de socket UDP?

No. QuicTransport no es un API de socket UDP. Si bien QUIC usa UDP “bajo el capó”, QuicTransport tiene requisitos en torno al cifrado y el control de la congestión que lo convierten en algo más que una API básica de UDP Socket.

¿Es QuicTransport una alternativa a los canales de datos WebRTC?

Sí, para conexiones cliente-servidor. QuicTransport comparte muchas de las mismas propiedades que Canales de datos WebRTC, aunque los protocolos subyacentes son diferentes.

Los canales de datos WebRTC admiten comunicaciones de igual a igual, pero QuicTransport solo admite la conexión cliente-servidor. Si tiene varios clientes que necesitan hablar directamente entre ellos, QuicTransport no es una alternativa viable.

Generalmente, ejecutar un servidor compatible con QUIC requiere menos instalación y configuración que mantener un servidor WebRTC, lo que implica comprender varios protocolos (HIELO, DTLSy SCTP) para conseguir un transporte que funcione. WebRTC implica muchas más piezas móviles que podrían conducir a negociaciones fallidas entre cliente y servidor.

La API de QuicTransport se diseñó teniendo en cuenta los casos de uso de los desarrolladores web y debería sentirse más como escribir un código de plataforma web moderno que utilizar las interfaces de canal de datos de WebRTC. A diferencia de WebRTC, QuicTransport se admite dentro de Trabajadores web, que le permite realizar comunicaciones cliente-servidor independientemente de una página HTML determinada. Porque QuicTransport expone un Corrientes-interfaz compatible, admite optimizaciones alrededor contrapresión.

Sin embargo, si ya tiene una configuración de cliente / servidor WebRTC en funcionamiento con la que está satisfecho, es posible que cambiar a QuicTransport no ofrezca muchas ventajas.

Pruébalo

La mejor forma de experimentar con QuicTransport es utilizar este código python para iniciar un servidor QUIC compatible localmente. A continuación, puede utilizar esta página con un cliente JavaScript básico para probar las comunicaciones cliente / servidor.

Usando la API

QuicTransport se diseñó sobre las primitivas de la plataforma web moderna, como API de Streams. Se basa en gran medida en promesasy funciona bien con async y await.

La prueba de origen de QuicTransport admite tres tipos distintos de tráfico: datagramas, así como flujos unidireccionales y bidireccionales.

Quizás te interesa >>>  Empezando a medir Web Vitals

Conectarse a un servidor

Puede conectarse a un servidor QUIC creando un QuicTransport ejemplo. El esquema de la URL debe ser quic-transport. Debe especificar explícitamente el número de puerto.

Deberías usar el ready promete esperar a que se establezca la conexión. Esta promesa no se cumplirá hasta que se complete la configuración y se rechazará si la conexión falla en la etapa QUIC / TLS.

los closed La promesa se cumple cuando la conexión se cierra normalmente y se rechaza si el cierre fue inesperado.

Si el servidor rechaza la conexión debido a una indicación del cliente error (por ejemplo, la ruta de la URL no es válida), entonces eso causa closed rechazar, mientras ready permanece sin resolver.

const url = 'quic-transport://example.com:4999/foo/bar';
const transport = new QuicTransport(url);


transport.closed.then(() => {
console.log(`The QUIC connection to ${url} closed gracefully.`);
}).catch((error) => {
console.error('The QUIC connection to ${url} closed due to ${error}.');
});


await transport.ready;

API de datagramas

Una vez que tenga una instancia de QuicTransport que esté conectada a un servidor, puede usarla para enviar y recibir bits de datos discretos, conocidos como datagramas.

los sendDatagrams() el método devuelve un WritableStream, que un cliente web puede utilizar para enviar datos al servidor. los receiveDatagrams() el método devuelve un ReadableStream, lo que le permite escuchar datos del servidor. Ambas transmisiones son inherentemente poco confiables, por lo que es posible que el servidor no reciba los datos que escriba, y viceversa.

Ambos tipos de corrientes utilizan Uint8Array instancias para la transferencia de datos.


const ws = transport.sendDatagrams();
const writer = ws.getWriter();
const data1 = new Uint8Array([65, 66, 67]);
const data2 = new Uint8Array([68, 69, 70]);
writer.write(data1);
writer.write(data2);


const rs = transport.receiveDatagrams();
const reader = rs.getReader();
while (true) {
const {value, done} = await reader.read();
if (done) {
break;
}
console.log(value);
}

Chrome no actualmente exponer un iterador asincrónico para ReadableStream. Por el momento, utilizando el getReader() método combinado con un while() loop es la mejor manera de leer de la secuencia.

API de Streams

Una vez que se haya conectado al servidor, también puede usar QuicTransport para enviar y recibir datos a través de sus API Streams.

Cada parte de todas las transmisiones es una Uint8Array. A diferencia de las API de datagramas, estos flujos son confiables. Pero cada flujo es independiente, por lo que no se garantiza el orden de los datos entre los flujos.

SendStream

UNA SendStream es creado por el cliente web utilizando el createSendStream() método de un QuicTransport instancia, que devuelve una promesa para el SendStream.

Utilizar el close() método del WritableStreamDefaultWriter asociado con la secuencia para enviar un QUIC Stream FIN bit al servidor. El navegador intenta enviar todos los datos pendientes antes de cerrar el flujo QUIC asociado.


const stream = await transport.createSendStream();
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}`);
}

Del mismo modo, utilice el abort() método del WritableStreamDefaultWriter para enviar un QUIC RESET_STREAM al servidor. Cuando usas abort(), el navegador puede descartar cualquier dato pendiente que aún no se haya enviado.

const ws = await transport.createSendStream();
const writer = ws.getWriter();
writer.write(...);
writer.write(...);
await writer.abort();

ReceiveStream

UNA ReceiveStream es iniciado por el servidor. Obtener un ReceiveStream es un proceso de dos pasos para un cliente web. Primero, llama al receiveStreams() método de un QuicTransport instancia, que devuelve una ReadableStream. Cada pedazo de eso ReadableStream, es, a su vez, un ReceiveStream que se puede usar para leer Uint8Array instancias enviadas por el servidor.

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

const rs = transport.receiveStreams();
const reader = rs.getReader();
while (true) {
const {done, value} = await reader.read();
if (done) {
break;
}
await readFrom(value);
}

Puede detectar el cierre de una corriente usando el closed promesa del ReadableStreamDefaultReader. Cuando la secuencia QUIC es cerrado con el bit FIN, la closed La promesa se cumple después de leer todos los datos. Cuando el flujo QUIC se cierra abruptamente (por ejemplo, por STREAM_RESET), entonces la closed promesa rechazada.


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

BidirectionalStream

UNA BidirectionalStream puede ser creado por el servidor o el cliente.

Los clientes web pueden crear uno usando el createBidirectionalStream() método de un QuicTransport instancia, que devuelve una promesa para un BidirectionalStream.

const stream = await transport.createBidirectionalStream();

Puedes escuchar un BidirectionalStream creado por el servidor con el receiveBidirectionalStreams() método de un QuicTransport instancia, que devuelve una ReadableStream. Cada pedazo de eso ReadableStream, es, a su vez, un BidirectionalStream.

const rs = transport.receiveBidrectionalStreams();
const reader = rs.getReader();
while (true) {
const {done, value} = await reader.read();
if (done) {
break;
}
}

UNA BidirectionalStream es solo una combinación de un SendStream y ReceiveStream. Los ejemplos de las dos secciones anteriores explican cómo utilizar cada uno de ellos.

Más ejemplos

los Proyecto de especificación de WebTransport incluye varios ejemplos en línea adicionales, junto con la documentación completa de todos los métodos y propiedades.

Habilitación de soporte durante la prueba de origen

  1. Solicita un token por tu origen.
  2. Agregue el token a sus páginas. Hay dos maneras de hacerlo:
    • Agregar un origin-trial <meta> etiqueta al encabezado de cada página. Por ejemplo, esto puede verse así:
      <meta http-equiv="origin-trial" content="TOKEN_GOES_HERE">
    • Si puede configurar su servidor, también puede agregar el token usando un Origin-Trial Encabezado HTTP. El encabezado de respuesta resultante debería verse así:
      Origin-Trial: TOKEN_GOES_HERE

QuicTransport en DevTools de Chrome

Desafortunadamente, DevTools de Chrome el soporte para QuicTransport no está listo para el inicio de la prueba de origen. Por favor, “estrella” este problema de Chrome para recibir notificaciones sobre actualizaciones en la interfaz de DevTools.

Consideraciones de privacidad y seguridad

Por favor vea el sección correspondiente del borrador de la especificación para una guía autorizada.

Retroalimentación

El equipo de Chrome desea escuchar sus pensamientos y experiencias al utilizar esta API durante todo el proceso de prueba de origen.

Comentarios sobre el diseño de la API

¿Hay algo en la API que es incómodo o no funciona como se esperaba? ¿O faltan piezas que necesitas para implementar tu idea?

Presentar un problema en el Repositorio de GitHub de transporte webo agregue sus pensamientos a un problema existente.

¿Problema con la implementación?

¿Encontraste un error con la implementación de Chrome?

Presentar un error en https://new.crbug.com. Incluya todos los detalles que pueda, junto con instrucciones sencillas para la reproducción.

¿Planea utilizar la API?

Su soporte público ayuda a Chrome a priorizar funciones y muestra a otros proveedores de navegadores lo importante que es brindarles soporte.

  • Asegúrese de haberse inscrito en el ensayo de origen para mostrar su interés y proporcionar su dominio e información de contacto.
  • Enviar un tweet a @Cromodev con #QuicTransport y detalles sobre dónde y cómo lo está usando.

Discusión General

Puedes usar el Web-transport-dev Grupo de Google para preguntas generales o problemas que no encajan en ninguna de las otras categorías.

Agradecimientos

Este artículo incorpora información de la Explicador de WebTransport, proyecto de especificacióny documentos de diseño relacionados. Gracias a los respectivos autores por brindar esa base.

La imagen principal de esta publicación es de Robin Pierre en Unsplash.