Los DataChannels basados en QUIC se consideran una alternativa al transporte SCTP actual. El grupo de trabajo de Google WebRTC ya está experimentando con ellos:
Probémoslo también. Para hacer esto, crearemos una aplicación de una página
similar al ejemplo de un canal WebRTC para enviar texto ; este es un ejemplo totalmente funcional (sin servidores de señalización), que, además, facilitará la comparación de enfoques para implementar WebCTC DataChannels.
Antes de comenzar, recordemos los conceptos básicos del
DataChannel .
Brevemente sobre DataChannel
Los DataChannels de WebRTC permiten a los participantes intercambiar datos arbitrarios. Pueden ser confiables, lo que es muy útil al transferir archivos, y poco confiables, lo cual es aceptable para obtener información sobre las posiciones en los juegos. La API es una extensión de
RTCPeerConnection
y tiene este aspecto:
const dc = pc.createDataChannel("some label string");
En la página oficial de muestras de WebRTC hay ejemplos de
envío de cadenas y
datos binarios .
DataChannel usa
SCTP . Funciona en paralelo con el transporte RTP para transmisiones de audio y video. A diferencia de UDP, que es comúnmente utilizado por transmisiones de audio y video, SCTP ofrece muchas otras características, como canales de multiplexación a través de una sola conexión o modos confiables, parcialmente confiables (es decir, confiables, pero desordenados) y poco confiables.
Google introdujo QUIC en 2012 (puede encontrar más información sobre el historial del protocolo y sus matices en
nuestro otro material : la nota del traductor). Al igual que WebRTC, el protocolo QUIC también se ha tomado bajo el ala del IETF y ahora es
HTTP / 3 . QUIC tiene una serie de grandes innovaciones, tales como: latencia reducida, cálculo de ancho de banda basado en control de congestión, corrección de retardo directo (FEC) e implementación en el espacio del usuario (en lugar del kernel) para un desplazamiento más rápido.
QUIC podría ser una alternativa a RTCP para WebRTC, como un transporte para DataChannel. El experimento actual está tratando de evitar el uso de la API RTCPeerConnection (¡
y SDP! ) Mediante el uso de una versión separada del transporte ICE. Piense en ello como una conexión virtual que agrega un poco de seguridad y una
gran cantidad de NAT transversal .
En el siguiente video, Ian Swett, del equipo de redes de Chrome, explica este concepto. Y aunque este discurso ha tenido varios años, aún proporciona información adicional sobre el tema:
Primeros pasos con QUIC
Afortunadamente, la mayor parte del
código del artículo de 2015 sigue siendo relevante y se adapta fácilmente a la nueva API. Vamos a resolverlo.
Clone el código
desde aquí o pruébelo
aquí . Tenga en cuenta que Chrome (la versión 73+ ahora es Canarias) debe ejecutarse con indicadores especiales para que el experimento funcione localmente:
google-chrome-unstable --enable-blink-features=RTCQuicTransport,RTCIceTransportExtension
Configuración de transporte ICE
La especificación RTCIceTransport se basa en ORTC, por lo que la configuración es similar al código anterior:
const ice1 = new RTCIceTransport(); ice1.onstatechange = function() { console.log('ICE transport 1 state change', ice1.state); }; const ice2 = new RTCIceTransport(); ice2.onstatechange = function() { console.log('ICE transport 2 state change', ice2.state); };
Tenga en cuenta que esta API no tiene RTCIceGatherer, a diferencia de ORTC. Porque ya tenemos todo lo que necesitamos para instalar el transporte ICE.
Configurar el transporte QUIC
const quic1 = new RTCQuicTransport(ice1); quic1.onstatechange = function() { console.log('QUIC transport 1 state change', quic1.state); }; const quic2 = new RTCQuicTransport(ice2); quic2.onstatechange = function() { console.log('QUIC transport 2 state change', quic2.state); };
Aquí, el experimento parte de una especificación que usa autenticación basada en certificados. En cambio, se usa la clave pública,
como dice la publicación de Google Developers :
La conexión RTCQuicTransport está configurada con una clave pública API. Actualmente no planeamos que esta API reemplace la validación original. Será reemplazado por un certificado remoto de señalización para validar certificados autofirmados, cuando QUIC comience a admitirlo en Chromium.
Hasta ahora todo bien.
QUICStream para enviar y recibir datos
Usar QUICStream es un poco más complicado que WebRTC DataChannel. La API Streams (
ver detalles sobre MDN ) creada por el grupo de trabajo WHATWG ha sido
aceptada pero no implementada .
Creamos
sendStream
solo después de que el transporte QUIC entra en el estado "conectado"; en un estado diferente, esto conduciría a un error:
quic1.onstatechange = function() { console.log('QUIC transport 1 state change', quic1.state); if (quic1.state === 'connected' && !sendStream) { sendStream = quic1.createStream('webrtchacks');
Luego adjuntamos los controladores al botón de enviar y al campo de entrada: después de hacer clic en el botón, el texto del campo de entrada se codifica en
Uint8Array y se escribe en la secuencia:
document.getElementById('sendButton').onclick = () => { const rawData = document.getElementById('dataChannelSend').value; document.getElementById('dataChannelSend').value = '';
La primera entrada activará el evento
onquicstream
en el transporte QUIC remoto:
... y luego esperamos que los datos sean legibles:
function ondata() { const buffer = new Uint8Array(receiveStream.readBufferedAmount); const res = receiveStream.readInto(buffer); const data = decoder.decode(buffer); document.getElementById('dataChannelReceive').value = data; receiveStream.waitForReadable(1) .then(ondata); }
Todos los datos de
receiveStream
se leerán, decodificarán en texto y se colocarán en el campo de salida. Y así, cada vez que aparecen datos legibles.
Conclusión y comentarios
Espero que este ejemplo sea más fácil de entender que el similar
en el blog de Google . Este método no es adecuado para conexiones P2P, el DataChannel en SCTP ya está funcionando bien para ellos. Sin embargo, esta puede ser una alternativa interesante a los sockets web con un servidor QUIC en el otro extremo. Hasta que esto suceda, debe determinar una forma decente de trabajar con canales poco confiables y desordenados. En mi opinión, las sugerencias de la publicación antes mencionada se parecen más a hacks que a decisiones.
Tampoco está claro qué comentarios esperan los desarrolladores del exterior. "Ya implementamos la especificación en lugar de esculpir nuevamente los atajos, que permanecerán con nosotros durante varios años", parece demasiado obvio. Además, la opinión general de la comunidad tiende a usar flujos de WHATWG, lo que pone en evidencia a los desarrolladores que piden probar su propia API para leer datos.
También me gustaría que SCTP en Chromium tenga características adicionales. Por ejemplo, esta
consulta sobre DataChannel , la mejor calificada, por cierto, ha permanecido casi intacta durante tres años. No está del todo claro por qué hay un enfoque en QUIC cuando todavía hay tareas SCTP; sin embargo, esto no debería impedir que nadie pruebe QUIC y reciba comentarios sobre los resultados.
Comentario de voximplant
Una palabra para nuestro
líder frontend irbisadm :
Durante mucho tiempo, nuestros SDK se han utilizado para señalizar un socket web. Este es un estándar excelente y probado en el tiempo, pero tiene algunos problemas. El primero es TCP. Y TCP no es tan bueno y rápido en redes móviles, además no admite roaming entre redes. En segundo lugar, a menudo es textual (también hay un modo binario, pero rara vez lo ves).
Recientemente lanzamos una prueba beta cerrada del protocolo de señalización en el DataChannel. Este protocolo tampoco está exento de inconvenientes, pero dado que funciona en redes deficientes y en itinerancia, conquista a primera vista. ¿Has cambiado la red? No es necesario recrear la conexión. ICE Restart
en la mayoría de los casos ayudará a encontrar una nueva forma de tráfico. Pero, como dije, el protocolo todavía tiene inconvenientes: no todos los navegadores admiten todas las extensiones de protocolo, como la entrega garantizada y el soporte de pedidos de paquetes; Además, el protocolo no admite gzip para el modo de texto fuera de la caja. Pero todos estos problemas pueden resolverse en el lado de la aplicación.