Millones de videollamadas por día o "¡Llama a mamá!"

Desde el punto de vista del usuario, los servicios de llamadas se ven bastante simples: vas a la página a otro usuario, llamas, él levanta el teléfono y hablas con él. Afuera parece que todo es simple, pero pocos saben cómo hacer ese servicio. Pero Alexander Tobol ( alatobol ) no solo lo sabe, sino que también comparte de buena gana su experiencia.



Además, la versión de texto del informe sobre HighLoad ++ Siberia, del cual aprenderá:

  • cómo funcionan los servicios de videollamadas bajo el capó;
  • lo hermoso que es romper NAT; esto será interesante para los especialistas en juegos que necesitan una conexión de igual a igual;
  • cómo funciona WebRTC, qué protocolos incluye;
  • ¿Cómo puedo sintonizar WebRTC a través de BigData?


Sobre el orador: Alexander Tobol lidera el desarrollo de las plataformas Video y Tape en ok.ru.

Historial de videollamadas


El primer dispositivo de videollamada apareció en 1960, se llamaba picherphone, utilizaba redes dedicadas y era extremadamente costoso. En 2006, Skype agregó videollamadas a su aplicación. En 2010, Flash admitió el protocolo RTMFP, y nosotros en Odnoklassniki lanzamos videollamadas Flash. En 2016, Chrome dejó de admitir Flash, y en agosto de 2017 reiniciamos las llamadas con la nueva tecnología, de la que hablaré hoy. Una vez finalizado el servicio, durante otros seis meses recibimos un aumento significativo en las llamadas completadas con éxito. Recientemente, también tenemos máscaras en llamadas.


Arquitectura y conocimientos tradicionales


Dado que trabajamos en una red social, no tenemos tareas técnicas y no sabemos qué es TK. Por lo general, toda la idea cabe en una página y se ve así.


El usuario quiere llamar a otros usuarios usando una aplicación web o iOS / Android. Otro usuario puede tener múltiples dispositivos. La llamada llega a todos los dispositivos, el usuario levanta el teléfono de uno de ellos y habla. Todo es simple

Especificaciones técnicas


Para realizar un servicio de llamadas de calidad, debemos comprender qué características queremos rastrear. Decidimos comenzar buscando qué es lo que más molesta al usuario.

El usuario definitivamente se molesta si levanta el teléfono y se ve obligado a esperar hasta que se establezca la conexión.


El usuario se molesta si la calidad de la llamada es deficiente: algo se interrumpe, el video se dispersa y el sonido burbujea.


Pero, sobre todo, el usuario está molesto por la demora en las llamadas. La latencia es una de las características importantes de las llamadas. Con una latencia en una conversación del orden de 5 segundos, es absolutamente imposible mantener un diálogo.


Hemos determinado por nosotros mismos las características aceptables:

  • Inicio : decidimos que era bueno comenzar la llamada en un segundo. Es decir conectarse después de que el usuario haya respondido, no debería tomar más de 1 segundo.
  • La calidad es un indicador muy subjetivo. Puede medir, por ejemplo, la relación señal-ruido (SNR), pero todavía faltan cuadros y otros artefactos. Medimos la calidad de manera bastante subjetiva y luego evaluamos la felicidad de los usuarios.
  • La latencia debe ser inferior a 0,5 segundos. Si la latencia es más de 0.5 segundos, entonces ya escucha demoras y comienza a interrumpirse entre sí.



Polycom es un sistema de conferencia instalado en nuestras oficinas. Tenemos latencias promedio de Polycom del orden de 1.3 segundos. Con tal retraso, no siempre se entienden entre sí. Si el retraso aumenta a 2 segundos, entonces el diálogo no será posible.


Como ya habíamos lanzado la plataforma, esperábamos que tuviéramos un millón de llamadas por día. Esto es mil llamadas en paralelo. Si todas las llamadas se inician a través del servidor, habrá mil megabits por llamada. Esto es solo 1 gigabit / seg. Un servidor de hierro será suficiente.

Internet vs TTX


¿Qué puede evitar que consigas características tan geniales? El internet!


En Internet, hay cosas como el tiempo de ida y vuelta (RTT), que no se pueden superar, hay un ancho de banda variable, hay NAT.

Anteriormente, medimos la velocidad de transmisión en las redes de nuestros usuarios.


Lo desglosamos por tipo de conexión, observamos el RTT promedio, la pérdida de paquetes, la velocidad y decidimos probar las llamadas en los valores promedio de cada una de estas redes.


Hay otros problemas en Internet:

  • Pérdida de paquetes : medimos una pérdida de paquetes aleatoria del 0,6% (no tenemos en cuenta la pérdida de paquetes de congestión con un número excesivo de paquetes).
  • Reordenamiento : envía paquetes en el mismo orden y la red los vuelve a ordenar.
  • Jitter : envíe una transmisión de video o audio a un cierto intervalo, y los paquetes se unen en el lado del cliente en paquetes, por ejemplo, debido al almacenamiento en búfer en los dispositivos de red.
  • NAT : resultó que más del 97% de los usuarios están detrás de NAT. Hablaremos sobre por qué, qué y cómo.



Considere la configuración de red enumerada anteriormente con un ejemplo simple.

Busqué el sitio web de la Universidad Estatal de Novosibirsk desde mi oficina y recibí un ping tan extraño.


El jitter promedio en este ejemplo es de 30 ms, es decir, el intervalo promedio entre tiempos de ping adyacentes es de aproximadamente 30 ms, y el ping promedio es de 105 ms.

¿Qué es importante en las llamadas, por qué lucharemos por p2p?


Obviamente, si logramos establecer una conexión p2p entre nuestros usuarios que intentan hablar entre ellos en San Petersburgo, y no a través de un servidor ubicado en Novosibirsk, ahorraremos aproximadamente 100 ms de ida y vuelta y tráfico a este servicio.

Por lo tanto, la mayor parte del artículo está dedicado a cómo hacer un buen p2p.

Historia o legado


Como dije, hemos tenido un servicio de llamadas desde 2010, y ahora lo hemos reiniciado.


En 2006, cuando Skype comenzó, Flash compró Amicima, que fabricó RTMFP. Flash ya tenía RTMP, que en principio se puede usar para llamadas, y a menudo se usa para transmisión. Flash luego abrió la especificación RTMP. Me pregunto por qué necesitaban RTMFP? En 2010, utilizamos RTMFP.

Compare los requisitos para los protocolos de llamadas y los protocolos de transmisión real y vea dónde está este límite.


RTMP es más un protocolo de transmisión de video. Utiliza TCP, tiene retraso acumulativo. Si tiene una buena conexión a Internet, las llamadas a RTMP funcionarán.

El protocolo RTMFP , a pesar de la diferencia en una sola letra, es el protocolo UDP. Está libre de problemas de almacenamiento en búfer, aquellos que están en TCP; Está privado de bloqueo de cabecera de línea: esto es cuando pierde un paquete y TCP no devuelve los siguientes paquetes hasta que es hora de enviar el perdido nuevamente. RTMFP pudo manejar NAT y estaba experimentando un cambio en la dirección IP de los clientes. Por lo tanto, lanzamos la web en RTMFP en 2010.


Entonces, solo en 2011 apareció el borrador inicial de WebRTC, que aún no estaba completamente operativo. En 2012, comenzamos a admitir llamadas en iOS / Android, luego sucedió algo más y en 2016 Chrome dejó de admitir Flash. Teníamos que hacer algo.


Analizamos todos los protocolos de VoIP: como siempre, para hacer algo, comenzamos mirando a los competidores.

Competidores o por dónde empezar


Elegimos los competidores más populares: Skype, WhatsApp, Google Duo (similar a Hangouts) e ICQ.

Para empezar, medimos el retraso.


Es facil de hacer. Arriba hay una fotografía en la que:

  • Cronómetro (vea el teléfono en la esquina superior izquierda), que muestra la hora (03:08).
  • El teléfono cercano hace una llamada y toma el primer teléfono como video. Desde el momento en que la imagen entró en la cámara del teléfono, y lo viste, tomó alrededor de 100 ms.
  • Una llamada a otro teléfono (blanco) y una vez más. Aquí el retraso es de aproximadamente 310 ms con Google Duo.

Todavía no revelaré todas las tarjetas, pero nos aseguramos de que estos dispositivos no pudieran establecer conexiones p2p. Por supuesto, las mediciones se llevaron a cabo en diferentes redes, y esto es solo un ejemplo.


Skype todavía interrumpe un poco. Resultó que con Skype, en caso de que no se conecte p2p, el retraso es de 1.1 s.

Nuestro entorno de prueba fue complicado. Probamos en diferentes condiciones (EDGE, 3G, LTE, WiFi), tomamos en cuenta que los canales son asimétricos, y doy los valores promedio de todas las mediciones.


Para estimar el consumo de batería, la carga en el procesador y todo lo demás, decidimos que simplemente puede medir la temperatura del teléfono con un pirómetro y asumir que esta es una carga promedio en la GPU del teléfono en el procesador, en la batería. En principio, es muy desagradable llevar un teléfono caliente a su oído e incluso sostenerlo en sus manos. Al usuario le parece que ahora la aplicación usará toda su batería.


El resultado es:

  • Los más lentos en el retraso fueron ICQ y Skype, y los más rápidos: Telegram. Esta no es una comparación completamente correcta, ya que Telegram no tiene videollamadas, pero tienen una latencia mínima en audio. WhatsApp (aproximadamente 200 ms) y Hangouts: 390 ms funcionan muy bien.
  • Por temperatura, Telegram come menos sin video y Skype más.
  • En términos de tiempo de respuesta , Telegram establece la conexión por el tiempo más largo y el WhatsApp y Google Duo más rápidos.

¡Genial, tenemos algunas métricas!


Probamos la calidad de video y voz en diferentes redes, con diferentes caídas y todo lo demás. Como resultado, llegamos a la conclusión de que el video de mayor calidad está en Google Duo, y la voz está en Skype , pero esto está en redes "malas" cuando ya hay distorsión. En general, todos trabajan aproximadamente mediocre. WhatsApp tiene la imagen más borrosa.

Veamos en qué se implementa todo.


Skype tiene su propio protocolo propietario, y todos los demás usan una modificación de WebRTC o, en general, directamente WebRTC. Hangouts, Google Duo, WhatsApp, Facebook Messenger pueden funcionar con la web, y todos tienen WebRTC bajo el capó. ¡Todos son muy diferentes, con diferentes características, y todos tienen un WebRTC! Por lo tanto, debe poder cocinarlo correctamente. Además, está Telegram, del cual algunas partes de WebRTC son responsables de la parte de audio, está ICQ, que bifurcó WebRTC durante mucho tiempo y siguió desarrollándose a su manera.

WebRTC Arquitectura




WebRTC implica la presencia de un servidor de señalización, un intermediario entre clientes, que se utiliza para intercambiar mensajes durante el establecimiento de una conexión p2p entre ellos. Después de establecer una conexión directa, los clientes comienzan a intercambiar datos multimedia entre ellos.

WebRTC Demo


Comencemos con una demostración simple. Hay 5 pasos simples para establecer una conexión WebRTC.

Código de ejemplo detallado
1. // Step #1: Getting local video stream and initializing a peer connection with it (both caller and callee) 2. 3. var localStream = null; 4. var localVideo = document.getElementById('localVideo'); 5. 6. navigator 7. .mediaDevices 8. .getUserMedia({ audio: true, video: true }) 9. .then(stream => { 10. localVideo.srcObject = stream; 11. localStream = stream; 12. }); 13. 14. var pc = new RTCPeerConnection({ iceServers: [...] }); 15. 16. localStream 17. .getTracks() 18. .forEach(track => pc.addTrack(track, localStream)); 19. 20. // Step #2: Creating SDP offer (caller) 21. 22. pc.createOffer({ offerToReceiveAudio: true, offerToReceiveVideo: true }) 23. .then(offer => signaling.send('offer', offer)); 24. 25. // Step #3: Handling SDP offer and sending SDP answer (callee) 26. 27. signaling.on('offer', offer => { 28. pc.setRemoteDescription(offer) 29. .then(() => pc.createAnswer()) 30. .then(answer => signaling.send('answer', answer)) 31. }); 32. 33. // Step #4: Handling SDP answer (calleer) 34. 35. signaling.on('answer', answer => pc.setRemoteDescription(answer)); 36. 37. // Step #5: Exchanging ICE candidates 38. 39. pc.onicecandidate = event => signaling.send('candidate', event.candidate); 40. 41. signaling.on('candidate', candidate => pc.addIceCandidate(candidate)); 42. 43. // Step #6: Getting remote video stream (both caller and callee) 44. 45. var remoteVideo = document.getElementById('remoteVideo'); 46. 47. pc.onaddstream = event => remoteVideo.srcObject = event.streams[0]; 


Dice lo siguiente:

  1. Grabe un video y establezca una conexión entre pares, transfiera algún tipo de iceServers (no está claro de inmediato qué es).
  2. Cree una oferta de SDP y envíela a señalización, y la señalización WebRTC no se implementará de ninguna manera.
  3. Luego debe hacer un contenedor para el que proviene de la señalización, y esto tampoco forma parte de WebRTC.
  4. Además intercambiar algunos candidatos.
  5. Finalmente obtenga la transmisión de video remota.

Veamos qué está sucediendo allí y qué necesitamos implementar nosotros mismos.


Nos fijamos en la imagen de abajo hacia arriba. Hay una biblioteca WebRTC que ya está integrada en el navegador, compatible con Chrome, Firefox, etc. Puede crearla en Android / iOS y comunicarse con ella a través de la API y SDP (Protocolo de descripción de sesión), que describe la sesión misma. A continuación te diré lo que está incluido en él. Para usar esta biblioteca en su aplicación, debe establecer una conexión entre suscriptores a través de la señalización. La señalización también es su servicio que debe escribir usted mismo, WebRTC no lo proporciona.

Más adelante en el artículo discutiremos la red en orden, luego video / audio, y al final escribiremos nuestra señalización.

Red WebRTC o p2p (en realidad c2s2c)


Configurar una conexión p2p parece ser bastante simple.


Tenemos a Alice y Bob que quieren establecer una conexión p2p. Toman sus direcciones IP, tienen un servidor de señalización al que ambos están conectados y a través del cual pueden intercambiar estas direcciones. Intercambian direcciones, y ¡oh! Tienen las mismas direcciones, ¡algo salió mal!


De hecho, es muy probable que ambos usuarios estén sentados detrás de enrutadores Wi-Fi y estas son sus direcciones IP grises locales. El enrutador les proporciona una función como la traducción de direcciones de red (NAT). Como trabaja ella?


Tiene una subred gris y una dirección IP externa. Usted envía un paquete a Internet desde su dirección gris, NAT reemplaza su dirección gris con blanco y recuerda la asignación: desde qué puerto envió, a qué usuario y con qué puerto coincide. Cuando llega el paquete de devolución, se resuelve mediante esta asignación y lo envía al remitente. Todo es simple

A continuación se muestra una ilustración de cómo se ve en mi lugar.


Esta es mi dirección IP interna y la dirección del enrutador (por cierto, también gris). Si traza y ve la ruta, veremos mi enrutador Wi-Fi: un paquete de direcciones de proveedores grises y una IP blanca externa. Por lo tanto, de hecho, tendré dos NAT: uno en el que estoy conectado a Wi-Fi y otro en el proveedor, a menos que, por supuesto, haya comprado una dirección IP externa dedicada.

NAT es muy popular porque:

  • todavía faltan muchos IPv4 y no hay suficientes direcciones;
  • NAT parece proteger la red;
  • Esta es una función estándar del enrutador: conectarse a Wi-Fi, hay NAT allí mismo, funciona.

Por lo tanto, solo el 3% de los usuarios se sientan con una IP externa, mientras que el resto pasa por NAT.

NAT le permite ir de forma segura a cualquier dirección blanca. Pero si no fuiste a ninguna parte, entonces nadie puede venir a ti.


Establecer una conexión p2p es un problema. De hecho, Alice y Bob no pueden enviarse paquetes entre sí si ambos están detrás de NAT.

WebRTC tiene un protocolo STUN para resolver este problema. Se propone implementar un servidor STUN. Luego, Alice se conecta al servidor STUN, obtiene su dirección IP y se la envía a Bob a través de la señalización. Bob también obtiene su dirección IP y se la envía a Alice. Se envían paquetes entre sí y, por lo tanto, rompen a través de NAT.


Pregunta : Alice tiene un puerto específico abierto, NAT / Firewall ya se ha roto a este puerto y Bob está abierto. Se conocen las direcciones del otro. Alice intenta enviar el paquete a Bob; él envía el paquete a Alice. ¿Crees que pueden hablar o no?

De hecho, tiene razón en cualquier caso, el resultado depende del tipo de par NAT que tengan los usuarios.


Traducción de direcciones de red


Hay 4 tipos de NAT:

  1. Cono completo NAT;
  2. Cono restringido NAT;
  3. Puerto restringido cono NAT;
  4. NAT simétrico

En la versión básica, Alice envía un paquete al servidor STUN, abre un puerto. Bob de alguna manera se entera de su puerto y envía un paquete de devolución. Si se trata de NAT de cono completo , el más fácil que simplemente asigna el puerto externo al puerto interno, entonces Bob podrá enviar inmediatamente un paquete a Alice, establecer una conexión y hablarán.


A continuación se muestra el esquema de interacción: Alice desde algún puerto envía un paquete al puerto STUN, STUN le responde con su dirección externa. STUN puede responder desde cualquier dirección, si es NAT de cono completo, seguirá atravesando NAT, y Bob puede responder a la misma dirección.


En el caso de NAT de cono restringido, las cosas son un poco más complicadas. Recuerda no solo el puerto desde el que debe asignar a la dirección interna, sino también la dirección externa a la que fue. Es decir, si ha establecido una conexión solo con el servidor IP STUN, nadie más en la red podrá responderle, y entonces el paquete de Bob no llegará.


¿Cómo se resuelve este problema? En un esquema simple (vea la ilustración a continuación) como este: Alice envía un paquete a STUN, él le responde con su IP. STUN puede responder desde cualquier puerto siempre que sea NAT de cono restringido. Bob no puede responder a Alice porque tiene una dirección diferente. Alice responde con un paquete, sabiendo la dirección IP de Bob. Ella abre NAT a Bob, Bob le responde. Hurra, hablaron.


Una opción un poco más complicada es el puerto NAT de cono restringido . De todos modos, solo STUN debe responder exactamente desde el puerto al que se accedió. Todo funcionará también.

Lo más dañino es NAT simétrica .


Al principio, todo funciona exactamente de la misma manera: Alice envía el paquete al servidor STUN y responde desde el mismo puerto. Bob no puede responder a Alice, pero ella le envía el paquete a Bob. Y aquí, a pesar de que Alice envía un paquete al puerto 4444, el mapeo le asigna un nuevo puerto. La NAT simétrica difiere en que cuando se establece cada nueva conexión, cada vez que emite un nuevo puerto en el enrutador. En consecuencia, Bob está golpeando en el puerto desde el cual Alice fue a STUN, y no pueden conectarse.

En la dirección opuesta, si Bob tiene una dirección IP abierta, Alice puede acercarse a él y establecerán una conexión.

Todas las opciones se recopilan en una tabla a continuación.


Muestra que casi todo es posible excepto cuando intentamos establecer conexiones a través de NAT simétrica con NAT de cono restringido de puerto o NAT simétrica en el otro extremo.


Como descubrimos, p2p no tiene precio para nosotros en términos de latencia, pero si no fue posible instalarlo, WebRTC nos ofrece un servidor TURN. Cuando nos dimos cuenta de que p2p no se instalará, solo podemos conectarnos a TURN, que representará todo el tráfico. Sin embargo, al mismo tiempo pagará por el tráfico, y los usuarios pueden tener algunos retrasos adicionales.

Practica


Google tiene servidores STUN gratuitos. Puedes ponerlos en la biblioteca, funcionará.

Los servidores TURN tienen credenciales (inicio de sesión y contraseña). Lo más probable es que tengas que criar la tuya, es bastante difícil de encontrar gratis.

Ejemplos de servidores STUN gratuitos de Google:

  • aturdimiento: stun.l.google.com: 19302
  • aturdimiento: stun1.l.google.com: 19302
  • aturdimiento: stun2.l.google.com: 19302
  • aturdimiento: stun3.l.google.com: 19302

Y un servidor TURN gratuito con contraseñas: url: 'turn: 192.158.29.39: 3478? Transport = udp', credencial: 'JZEOEt2V3Qb0y27GRntt2u2PAYA =', nombre de usuario: '28224511: 1379330808'.

Usamos coturn .


Como resultado, el 34% del tráfico pasa a través de la conexión p2p, todo lo demás se representa a través del servidor TURN.

¿Qué más es interesante en el protocolo STUN?


STUN le permite determinar el tipo de NAT.


Enlace de diapositivas

Al enviar un paquete, puede indicar que desea recibir una respuesta desde el mismo puerto o pedirle a STUN que responda desde un puerto diferente, desde una IP diferente o incluso desde una IP y puerto diferentes. Por lo tanto, para 4 consultas al servidor STUN, puede determinar el tipo de NAT .


Contamos los tipos de NAT y obtuvimos que casi todos los usuarios tienen NAT simétrica o NAT de cono restringido a puertos. Por lo tanto, resulta que solo un tercio de los usuarios pueden establecer una conexión p2p.

Puede preguntar por qué le estoy contando todo esto si solo pudiera tomar el STUN de Google, ponerlo en WebRTC, y parece que todo funcionará.

Porque puedes determinar el tipo de NAT tú mismo.


Este es un enlace a una aplicación Java que no hace nada complicado: solo hace sonar diferentes puertos y diferentes servidores STUN, y mira qué puerto ve al final. Si tiene Open Full cone NAT, el servidor STUN tendrá el mismo puerto. Con NAT de cono restringido, tendrá diferentes puertos para cada solicitud STUN.


Con NAT simétrica, resulta así en mi oficina. Hay puertos completamente diferentes.

Pero a veces hay un patrón interesante que para cada conexión, el número de puerto aumenta en uno.


Es decir, muchos NAT están configurados para que aumenten o disminuyan el puerto de forma constante. Esta constante se puede encontrar y así romper a través de NAT simétrica.


Por lo tanto, rompemos a través de NAT: vamos a un servidor STUN, a otro, observamos la diferencia, comparamos e intentamos nuevamente dar nuestro puerto con este incremento o decremento. Es decir, Alice está tratando de darle a Bob su puerto, ya ajustado para una constante, sabiendo que la próxima vez será solo eso.


Así que logramos soldar otro 12% de igual a igual .

De hecho, a veces los enrutadores externos con la misma IP se comportan igual. Por lo tanto, si recopila estadísticas y si Symmetric NAT es una función del proveedor y no una función del enrutador Wi-Fi del usuario, entonces se puede predecir el delta, envíelo inmediatamente al usuario para que lo use y no pase demasiado tiempo determinándolo.

CDN Relay o qué hacer si no puede establecer una conexión P2P


Si todavía utilizamos el servidor TURN y no trabajamos en p2p, sino en modo real, pasando todo el tráfico a través del servidor, aún podemos agregar un CDN. A menos, por supuesto, que tenga un parque infantil. Tenemos nuestros propios sitios de CDN, por lo que para nosotros fue bastante simple. Pero era necesario determinar dónde es mejor enviar a una persona: a un sitio de CDN o, por ejemplo, a un canal a Moscú. Esta no es una tarea muy trivial, así que hicimos esto:

  1. Emitido accidentalmente a algunos usuarios del sitio de Moscú, algunos remotos.
  2. Recopilamos estadísticas sobre la IP del usuario, los servidores y las características de la red.
  3. Por maxMind, agrupamos las subredes, miramos las estadísticas y pudimos entender por IP qué usuario tenía el servidor TURN más cercano para la conexión.



Hay un CDN en Novosibirsk. Si todo funciona para usted en Moscú, entonces el percentil 99 de RTT es 1.3 segundos. A través de CDN, todo funciona mucho más rápido (0,4 segundos).

¿Siempre es mejor usar una conexión p2p y no usar un servidor? Un ejemplo interesante son los dos proveedores de Krasnoyarsk, Optibyte y Mobra (los nombres pueden haber cambiado). Por alguna razón, la conexión entre ellos en p2p es mucho peor que a través de MSK. Probablemente no son amigos entre sí.


Analizamos todos estos casos, enviando aleatoriamente a los usuarios a p2p o vía MSK, recopilamos estadísticas y construimos predicciones. Sabemos que las estadísticas deben actualizarse, por lo que para algunos usuarios establecemos especialmente conexiones diferentes para verificar si algo ha cambiado en las redes.

Medimos características tan simples como el tiempo de ronda, la pérdida de paquetes, el ancho de banda: queda por aprender cómo compararlos correctamente.


¿Cómo entender cuál es mejor: 2 Mbit / s de Internet, 400 ms RTT y 5% de pérdida de paquetes o 100 Kbit / s, 100 ms de retraso y escasa pérdida de paquetes?

No hay una respuesta exacta, la evaluación de la calidad de las videollamadas es muy subjetiva. Por lo tanto, después del final de la llamada, pedimos a los usuarios que evaluaran la calidad de los asteriscos y establecieran las constantes de acuerdo con los resultados. Resultó que, por ejemplo, RTT es inferior a 300 ms: ya no importa, la tasa de bits es más importante.

Mayores calificaciones de usuario en Android e iOS. Se ve que los usuarios de iOS tienen más probabilidades de poner una unidad y más a menudo cinco. No sé por qué, probablemente, los detalles de la plataforma. Pero arrastramos las constantes a lo largo de ellas, de modo que tuvimos, como nos parece, bueno.

Volviendo a nuestro esquema para el artículo, todavía estamos discutiendo la red.

¿Cómo se ve la configuración de la conexión?


Enviamos servidores STUN y TURN a PeerConnection (), se establece una conexión. Alice descubre su IP, la envía a señalización; Bob se entera de la IP de Alice. Alice obtiene la IP de Bob. Intercambian paquetes, tal vez rompen a través de NAT, tal vez establecen TURN y se comunican.


En los 5 pasos para establecer la conexión que discutimos anteriormente, descubrimos los servidores, descubrimos dónde obtenerlos y que los candidatos de ICE son direcciones IP externas que intercambiamos a través de la señalización. Las direcciones IP internas de los clientes, si están dentro del alcance de un Wi-Fi, también se pueden intentar para romper.

Pasemos a la parte del video.

Video y audio


WebRTC admite un cierto conjunto de códecs de video y audio, pero puede agregar su propio códec allí. Básicamente compatible con H.264 y VP8 para video . VP8 es un códec de software, por lo tanto, consume mucha batería. H.264 no está disponible en todos los dispositivos (generalmente es nativo), por lo que la prioridad predeterminada es VP8.

Dentro del SDP (Protocolo de descripción de sesión), existe una negociación de códec: cuando un cliente envía una lista de sus códecs, el otro envía los suyos con prioridad, y acuerdan qué códecs utilizarán para la comunicación. Si lo desea, puede cambiar la prioridad de los códecs VP8 y H.264, y debido a esto, puede ahorrar batería en algunos dispositivos, donde 264 es nativo. Aquí hay un ejemplo de cómo se puede hacer esto. Hicimos esto, nos pareció que los usuarios no se quejaron de la calidad, pero al mismo tiempo la carga de la batería se consumió mucho menos.

Para el audio, WebRTC tiene OPUS o G711 , generalmente todos los OPUS siempre funcionan, no es necesario hacer nada con él.

A continuación se muestran las mediciones de temperatura después de 10 minutos de uso.


Está claro que probamos diferentes dispositivos. Este es un ejemplo de un iPhone, y en él, la aplicación OK utiliza menos la batería, porque la temperatura del dispositivo es la menor.

La segunda cosa que puede habilitar si usa WebRTC es apagar automáticamente el video cuando la conexión es muy deficiente .


Si tiene menos de 40 Kbps, el video se apagará. Solo necesita marcar la casilla al crear la conexión, el valor umbral se puede configurar a través de la interfaz. También puede establecer la tasa de bits de arranque actual mínima y máxima.


Esto es algo muy útil. Si cuando establece una conexión, sabe de antemano qué tasa de bits espera, puede transferirla, la llamada comenzará desde ella y no necesitará adaptar la tasa de bits. Además, si sabe que a menudo tiene pérdida de paquetes o reducción de ancho de banda en su canal, entonces el valor máximo también puede ser limitado.

WhatsApp funciona con videos muy jabonosos, pero con pequeños retrasos, ya que comprime agresivamente la tasa de bits desde arriba.

Recopilamos estadísticas usando MaxMind y lo mapeamos.


Esta es una calidad inicial aproximada que utilizamos para llamadas en diferentes regiones de Rusia.

Señalización


Lo más probable es que tenga que escribir esta parte si desea hacer llamadas. Hay todo tipo de trampas. Recordemos cómo se ve.


Hay una aplicación con señalización que se conecta e intercambia con SDP, y el SDP a continuación es la interfaz para WebRTC.

Así es como se ve la señalización simple:


Alice llama a Bob. Se conecta, por ejemplo, a través de una conexión de socket web. Bob recibe un impulso en su teléfono móvil o navegador, o en alguna conexión abierta, se conecta a través de un enchufe web y luego el teléfono comienza a sonar en su bolsillo. Bob levanta el teléfono, Alice le envía sus códecs y otras características de WebRTC que admite. Bob le responde lo mismo, y después de eso intercambian los candidatos que vieron. ¡Hurra, llama!

Todo parece bastante largo. Primero, hasta que establezca una conexión de socket web, hasta que llegue el empuje y todo lo demás, el teléfono de Bob no sonará en su bolsillo. Alice esperará todo el tiempo, pensará dónde está Bob, por qué no levanta el teléfono. Después de la confirmación, todo lleva segundos, e incluso en buenas conexiones puede ser de 3 a 5 segundos, y en malas conexiones, todos los 10.

¡Debemos hacer algo al respecto! Me dirás que todo se puede hacer de manera muy simple.



Si ya tiene una conexión abierta para su aplicación, puede enviar inmediatamente un impulso para establecer una conexión, conectarse al servidor de señalización deseado e inmediatamente comenzar a hacer llamadas.

Luego otra optimización. Incluso si el teléfono sigue sonando en su bolsillo y no lo ha recogido, puede intercambiar información sobre los códecs compatibles, las direcciones IP externas, comenzar a enviar paquetes de video vacíos y, en general, todo se calentará. Una vez que levante el teléfono, todo será genial.

Lo hicimos, y parecía que todo estaba bien. Pero no


El primer problema es que los usuarios a menudo cancelan la llamada. Hacen clic en "Llamar" e inmediatamente se cancelan. En consecuencia, el impulso se dirige a la llamada y el usuario desaparece (ha perdido Internet u otra cosa). Mientras tanto, suena el teléfono de alguien, levanta el teléfono y no se lo espera allí. Por lo tanto, nuestra optimización primitiva para comenzar a llamar lo más rápido posible realmente no funciona.


Con una cancelación de llamada rápida, hay una segunda cosa dañina. Si genera la ID de su conversación en el servidor, entonces debe esperar una respuesta. Es decir, crea una llamada, obtiene una identificación y solo después de eso puede hacer lo que quiera: enviar paquetes, intercambiar, incluso cancelar la llamada. Esta es una historia muy mala, porque resulta que hasta que llegue la respuesta, en realidad no puede cancelar nada del cliente. Por lo tanto, es mejor generar algún tipo de ID en el cliente, como un GUID y decir que inició la llamada. La gente a menudo hace esto: llamaron, cancelaron e inmediatamente volvieron a llamar. Para evitar que esto se estropee, haga un GUID y envíelo.


Parece no ser nada, pero hay otro problema. Si Bob tiene dos teléfonos, o en algún otro lugar el navegador permanece abierto, entonces todo nuestro esquema mágico para intercambiar paquetes, establecer una conexión no funciona si de repente responde desde otro dispositivo.

Que hacer Volvamos a nuestro esquema básico simple de señalización lenta y optimícelo, envíe el empuje un poco antes. El usuario comenzará a conectarse más rápido, pero esto ahorrará algunos centavos.


¿Qué hacer con la parte más larga después de que levantó el teléfono y comenzó el intercambio?


Puedes hacer lo siguiente. Está claro que Alice ya conoce todos sus códecs y puede enviarlos a los dos teléfonos de Bob. Puede resolver todas sus direcciones IP y también enviarlas a la señalización, lo que las mantendrá en su cola, pero no enviará a ninguno de los clientes para que puedan comenzar a conectarse con ella con anticipación.

? offer, , , , , , . , codec negotiation, signaling , , . Candidates signaling.

, signaling . , , .

. Google Duo WhatsApp.


, - . , signaling, , , , , , . .

?


: , . , , — signaling , , - , , , .


, , , . . , , , , . , .

, 24/7, -, .




web-socket - load balancer, signaling- -, . Zookeeper Leader Election, signaling, conversation. conversation, .

, NewSQL Cassandra . , . , signaling, , signaling, - , Leader Election Zookeeper, , , .

:

  • - , , IP signaling
  • Signaling , .
  • , , , , .
  • .

, .

Cassandra, ( ).

, :

  • iceServers ;
  • Session Description Protocol;
  • ;
  • signaling WebRTC , IP ;
  • !



:

  • delay ;
  • ;
  • .

Wow!


Security. Man in the middle attack for WebRTC


man in the middle attack for WebRTC. , WebRTC , RTP, 1996 , SDP 1998 SIP.


— RFC RTP, RTP WebRTC.

RFC — audio level, , audio level , . , SDP, , . congestion, -.

WebRTC . 2011 , 2013 Firefox, iOS/Android, 2014 Opera. , - , .


signaling, , DTLS Handshake . , signaling, «» , , , .


, , , HTTPS, WSS .. — ZRTP, , , Telegram.

Telegram , , . , , , , p2p .

Como funciona


— . , , . . K, , , .

, , K 1 K 2 . . . K 1 K 2 , . K 1 K 2 : , — , — , . , , - , , .



  • «» NAT type symmetric NAT.
  • , : 2 relay, , CDN; .
  • , .
  • signaling.



, RTMFP, , WebRTC, , . ! 4 .



, :


, .



HighLoad++ 4-.

, . , 19 (10 9 -) , - . , , .

Source: https://habr.com/ru/post/es428217/


All Articles