Saltar al contenido principal
Dev

Experimentando con WebTransport

Por 21/11/2020julio 6th, 2021Comentarios no habilitados

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.

igraal_es-es


Actualizado

Precaución: Esta iniciativa 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 consecuencia, parte de la información y todo el código de muestra de este post está desactualizado. Para conocer las últimas novedades sobre esta iniciativa 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 iniciativa se estabilice, actualizaremos este post y los ejemplos de código asociados con información actualizada.

Antecedentes

¿Qué es QuicTransport?

QuicTransport es una API web que usa 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 mediante sus API de datagramas y de manera confiable mediante 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 requiere enviar o recibir uno o más flujos de datos ordenados. El uso de diversos flujos QUIC es análogo a determinar diversos 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 Iniciativa 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 usar 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 ha tomado la decisión de empezar con QuicTransport luego 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 utilizar QuicTransport.

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

Como parte del procedimiento de prueba de origen, estamos interesados ​​en conocer más acerca de cómo planea utilizar 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

Vinculación de QuicTransport con otras tecnologías

¿QuicTransport es un reemplazo de WebSockets?

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

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 requiere esas características, las API de streams de QuicTransport además 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, mediante las API de datagramas o a través de diversos instancias de API de Streams simultáneas, significa que no tiene que preocuparse por bloqueo de cabecera de línea, que puede ser un obstáculo con WebSockets. Al mismo tiempo, existen beneficios de rendimiento al determinar nuevas conexiones, dado 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 en este momento mucho más sólido. Si requiere 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 en este momento.

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

No. QuicTransport no es un API de socket UDP. Aunque QUIC utiliza UDP «bajo el capó», QuicTransport tiene requerimientos 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, aún cuando 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 cuenta con varios clientes que necesitan hablar de forma directa entre ellos, QuicTransport no es una opción posible.

De forma general, ejecutar un servidor compatible con QUIC necesita menos instalación y configuración que mantener un servidor WebRTC, lo que conlleva entender varios protocolos (HIELO, DTLSy SCTP) para obtener un transporte que funcione. WebRTC conlleva 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 usar las interfaces de canal de datos de WebRTC. A diferencia de WebRTC, QuicTransport se admite dentro de Empleados web, que le posibilita realizar comunicaciones cliente-servidor sin tener en cuenta una página HTML determinada. Debido a que QuicTransport expone un Corrientes-interfaz compatible, admite optimizaciones alrededor contrapresión.

No obstante, si ya dispone de una configuración de cliente / servidor WebRTC en funcionamiento con la que está satisfecho, es viable que cambiar a QuicTransport no ofrezca muchas ventajas.

Pruébalo

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

Utilizando la API

QuicTransport se diseñó sobre las primitivas de la plataforma web moderna, como API de Streams. Se basa en gran medida en promesasy va bastante 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.

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 utilizar 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 fase QUIC / TLS.

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

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

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


transport.closed.then(() => {
console.log(`The QUIC connection to ${dirección url} closed gracefully.`);
}).catch((error) => {
console.error('The QUIC connection to ${dirección 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 usar para enviar datos al servidor. los receiveDatagrams() el método devuelve un ReadableStream, lo que le posibilita escuchar datos del servidor. Ambas transmisiones son inherentemente poco confiables, por lo que es viable que el servidor no reciba los datos que escriba, y viceversa.

Ambos tipos de corrientes usan 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 en este momento exponer un iterador asincrónico para ReadableStream. Por el momento, usando 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, además puede utilizar QuicTransport para enviar y recibir datos mediante 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 usando el createSendStream() método de un QuicTransport instancia, que devuelve una promesa para el SendStream.

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

De la misma forma, 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 todavía 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. Conseguir un ReceiveStream es un procedimiento 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 utilizar 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 utilizando el closed promesa del ReadableStreamDefaultReader. Cuando la secuencia QUIC es cerrado con el bit FIN, la closed La promesa se alcanza luego de leer todos los datos. Cuando el flujo QUIC se cierra abruptamente (a modo de 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 utilizando 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 usar 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. A modo de ejemplo, esto puede verse así:
      <meta http-equiv="origin-trial" content="TOKEN_GOES_HERE">
    • Si puede configurar su servidor, además puede agregar el token utilizando 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 respectivo del borrador de la especificación para una guía autorizada.

Retroalimentación

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

Comentarios sobre el diseño de la API

¿Puede haber algo en la API que es incómodo o no funciona como se esperaba? ¿O faltan piezas que necesitas para poner en práctica tu idea?

Presentar un obstáculo en el Repositorio de GitHub de transporte webo agregue sus pensamientos a un obstáculo 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 usar 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á utilizando.

Discusión General

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

Agradecimientos

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

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

error: Atención: Contenido protegido.