¿Qué?
RTCQuicTransport es una API de plataforma web nueva que permite intercambiar datos arbitrarios con pares remotos mediante el protocolo QUIC. Se diseñó para casos de uso entre pares y, por lo tanto, se utiliza con una API de RTCIceTransport independiente para establecer una conexión entre pares mediante ICE. Los datos se transportan de manera confiable y en orden (consulta la sección a continuación para obtener detalles sobre la entrega no confiable y sin ordenar). Como es un transporte de datos genérico y bidireccional, se puede usar para videojuegos, transferencias de archivos, transporte de contenido multimedia, mensajería, etcétera.
¿Por qué?
Una API de transporte de datos de bajo nivel y potente puede permitir que las aplicaciones (como las comunicaciones en tiempo real) realicen tareas nuevas en la Web. Puedes compilar sobre la API si creas tus propias soluciones y desafías los límites de lo que se puede hacer con las conexiones entre pares, por ejemplo, desbloquear controles de asignación de tasa de bits personalizados. En el futuro, una mayor compatibilidad con contenido multimedia codificado podría permitir compilar tu propia aplicación de comunicación por video con controles de bajo nivel. El esfuerzo de NV de WebRTC es avanzar hacia APIs de nivel inferior, y experimentar con esto es valioso.
¿Por qué QUIC?
El protocolo QUIC es conveniente para las comunicaciones en tiempo real. Se basa en UDP, tiene encriptación y control de congestión integrados, y es multiplexado sin bloqueo de cabeza de línea. RTCQuicTransport
proporciona capacidades muy similares a las de la API de RTCDataChannel
, pero usa QUIC en lugar de SCTP como protocolo de transporte. Como RTCQuicTransport
es una API independiente, no tiene la sobrecarga de la API de RTCPeerConnection
, que incluye la pila de medios en tiempo real.
¿Cómo?
Descripción general de la API
La API tiene 3 abstracciones principales: RTCIceTransport
, RTCQuicTransport
y RTCQuicStream
.
RTCIceTransport
ICE es un protocolo para establecer conexiones entre pares por Internet y actualmente se usa en WebRTC. Este objeto proporciona una API independiente para establecer una conexión ICE. Se usa como transporte de paquetes para la conexión QUIC, y RTCQuicTransport
lo toma en su constructor.
RTCQuicTransport
Representa una conexión QUIC. Se usa para establecer una conexión QUIC y crear transmisiones QUIC. También expone estadísticas relevantes para el nivel de conexión de QUIC.
RTCQuicStream
Se utiliza para leer y escribir datos hacia y desde el lado remoto. Las transmisiones transportan datos
de manera confiable y en orden. Se pueden crear varias transmisiones desde el mismo RTCQuicTransport
y, una vez que se escriben los datos en una transmisión, se activa un evento “onquicstream” en el transporte remoto. Las transmisiones ofrecen una forma de distinguir datos diferentes en la misma conexión QUIC. Algunos ejemplos comunes pueden ser el envío de archivos separados entre transmisiones separadas, pequeños fragmentos de datos en diferentes transmisiones o diferentes tipos de contenido multimedia en transmisiones separadas. Los elementos RTCQuicStream
son livianos, se multiplexan mediante una conexión QUIC y no causan bloqueo de cabeza de línea a otros RTCQuicStream
.
Configuración de la conexión
El siguiente es un ejemplo para configurar una conexión QUIC entre pares.
Al igual que RTCPeerConnection
, la API de RTCQuicTransport
requiere el uso de un canal de señalización seguro para negociar los parámetros de la conexión, incluidos sus parámetros de seguridad. El RTCIceTransport
negocia sus parámetros de ICE (ufrag y contraseña), así como los RTCIceCandidate
.
Perspectiva del cliente:
const iceTransport = new RTCIceTransport();
const quicTransport = new RTCQuicTransport(iceTransport);
// Signal parameters, key and candidates.
signalingChannel.send({
iceParams: iceTransport.getLocalParameters(),
quicKey: quicTransport.getKey(),
});
iceTransport.onicecandidate = e => {
if (e.candidate) {
signalingChannel.send({candidate: e.candidate});
}
};
// When remote parameters are signaled, start connection.
signalingChannel.onMessage = async ({iceParams, candidate}) => {
if (iceParams) {
iceTransport.start(iceParams);
quicTransport.connect();
} else if (candidate) {
iceTransport.addRemoteCandidate(candidate);
}
};
Perspectiva del servidor:
const iceTransport = new RTCIceTransport();
const quicTransport = new RTCQuicTransport(iceTransport);
// Signal parameters, key and candidates.
signalingChannel.send({
iceParams: iceTransport.getLocalParameters(),
});
iceTransport.onicecandidate = e => {
if (e.candidate) {
signalingChannel.send({candidate: e.candidate});
}
};
// When remote parameters are signaled, start connection.
signalingChannel.onMessage = async ({iceParams, quicKey, candidate}) => {
if (iceParams && quicKey) {
iceTransport.start(iceParams);
quicTransport.listen(quicKey);
} else if (candidate) {
iceTransport.addRemoteCandidate(candidate);
}
};
Transferencia de datos
La transferencia de datos se puede lograr con las APIs de RTCQuicStream para la lectura y la escritura:
RTCQuicStreamReadResult readInto(Uint8Array data);
void write(RTCQuicStreamWriteParameters data);
Promise<void> waitForWriteBufferedAmountBelow(unsigned long amount);
Promise<void> waitForReadable(unsigned long amount);
Interrupciones por almacenamiento en búfer
Las promesas que muestran los métodos waitFor*
permiten almacenar datos en búfer cuando JavaScript está ocupado. La contrapresión se aplica al lado de envío cuando el búfer de lectura se llena en el lado receptor. El lado de envío tiene un búfer de escritura que puede llenarse cuando se aplica la contrapresión y, por lo tanto, el lado de escritura también tiene un método waitForWriteBufferedAmountBelow
a fin de permitir la espera de espacio en el búfer para escribir. Puedes encontrar más información sobre cómo escribir y leer datos en la documentación adicional para desarrolladores.
Entrega no confiable o sin pedidos
Si bien un RTCQuicStream
solo admite el envío de datos de manera confiable y en orden, la entrega no confiable o desordenada se puede lograr a través de otros medios. Para la entrega desordenada, se pueden enviar pequeños fragmentos de datos en transmisiones separadas porque los datos no están ordenados entre transmisiones. Para una entrega poco confiable, se pueden enviar pequeños fragmentos de datos con el valor "Finish" establecido en verdadero y, luego, llamar a reset()
en la transmisión después de que se agote el tiempo de espera. El tiempo de espera debe depender de cuántas retransmisiones se desean antes de descartar los datos.
¿Cuándo?
La prueba de origen comenzará en la versión de Chrome 73 y estará disponible hasta la versión M75 inclusive. Después de esto, finalizará la prueba de origen. En función de los comentarios y el interés, realizaremos los cambios adecuados y enviaremos la API, continuaremos con una nueva prueba de origen de esta API o descontinuaremos la API.
¿Dónde?
Navegador Chrome en todas las plataformas, excepto iOS.
¿Qué más?
Comentarios
Uno de los objetivos principales de la prueba de origen es recibir comentarios de ustedes, los desarrolladores. Nos interesa lo siguiente:
- ¿Qué te permite usar esta API?
- ¿Cómo mejora esta API en comparación con otras APIs de transporte de datos (
WebSocket
oRTCDataChannel
de WebRTC)? ¿Cómo podría hacerlo? - Rendimiento
- Ergonomía de las APIs
Regístrate para la prueba de origen
- Solicita un token para tu origen.
- Para agregar el token a tus páginas, hay dos formas de hacerlo en cualquier página de tu origen:
- Agrega una etiqueta
origin-trial
<meta>
al encabezado de cualquier página. Por ejemplo, es posible que se vea de la siguiente manera:<meta http-equiv="origin-trial" content="TOKEN_GOES_HERE">
- Si puedes configurar tu servidor, también puedes proporcionar el token en páginas con un encabezado HTTP
Origin-Trial
. El encabezado de respuesta resultante debería verse de la siguiente manera:Origin-Trial: TOKEN_GOES_HERE
- Agrega una etiqueta
Especificación web
La especificación del borrador se adelantó a la API en la prueba de origen, que incluye lo siguiente:
- Transmisiones unidireccionales que están más alineadas con las transmisiones de WhatWG
- Inhabilita las retransmisiones
- Datagramas (próximamente)
Nos interesa implementar la especificación completa y mucho más (incluida la compatibilidad con flujos de WhatWG), pero primero queremos conocer tus comentarios.
Seguridad
La seguridad en el protocolo de enlace QUIC se aplica mediante el uso de una clave compartida previamente para establecer una conexión P2P QUIC encriptada. Esta clave debe indicarse a través de un canal seguro fuera de banda con garantías de confidencialidad y de integridad. Ten en cuenta que la clave se expondrá a JavaScript.
Ataque activo
A diferencia de DTLS-SRTP, que solo requiere integridad para indicar la huella digital del certificado, indicar que la clave precompartida requiere integridad y confidencialidad. Si la PSK está comprometida (por ejemplo, por el servidor en el canal de señalización), un atacante activo podría activar un ataque de intermediario contra el protocolo de enlace QUIC.
Estado actual
Step | Estado |
---|---|
1. Crear explicación | Completo |
**2a. Especificación de RTCQuicTransport ** | **En curso** |
**2b. Especificación de RTCIceTransport ** | **En curso** |
**3. Recopila comentarios y, luego, itera sobre el diseño** | **En curso** |
4. Prueba de origen | ¡Comienza en Chrome 73! |
5. Lanzamiento | No iniciada |
Vínculos útiles
- Documentación adicional
- Explicación pública
- Error de seguimiento
- Solicitar un token de prueba de origen
- Cómo usar un token de prueba de origen
- Debate sobre problemas para RTCQuicTransport
- Debate sobre problemas para RTCIceTransport