WebRTC. Videoconferencia en el navegador. Chat multiusuario usando WebRTC Chat de voz Webrtc

Preámbulo. Video chat P2P activado Base WebRTC es una alternativa a Skype y otros medios de comunicación. Los elementos principales del video chat p2p basado en WebRTC son un navegador y un servidor de contactos. Los videochats P2P son videochats peer-to-peer en los que el servidor no participa en la transmisión de flujos de información. La información se transfiere directamente entre los navegadores de los usuarios (pares) sin ningún programas adicionales. Además de los navegadores, los videochats p2p utilizan servidores de contactos, que están diseñados para registrar usuarios, almacenar datos sobre ellos y garantizar el cambio entre usuarios. Los navegadores que admiten las últimas tecnologías WebRTC y HTML5 brindan mensajería de texto instantánea y transmisión de archivos, así como comunicación de voz y video a través de redes IP.

Entonces, chats, chats web, chats de voz y video en una interfaz web, IMS, VoIP son servicios que brindan comunicaciones en línea a través de redes compuestas de conmutación de paquetes. Como regla general, los servicios de comunicación requieren la instalación de aplicaciones cliente en los dispositivos de los usuarios (PC, teléfonos inteligentes, etc.) o la instalación de complementos y extensiones en los navegadores. Los servicios tienen sus propias redes de comunicación, la mayoría de las cuales se basan en una arquitectura cliente-servidor.

Los servicios de comunicaciones son aplicaciones, distintas de IMS, en las que los canales de voz, vídeo, datos y texto no están integrados. En las redes de cada servicio, . Cabe señalar que estas aplicaciones no pueden funcionar simultáneamente en varias redes de comunicación, es decir. Por lo general, las aplicaciones no pueden comunicarse entre sí, lo que requiere la instalación de una aplicación independiente para cada red de comunicación.

El problema de integrar servicios de comunicación en tiempo real (chat, telefonía, videoconferencia), es decir. La integración de canales de voz, video y datos y el acceso a ellos mediante una aplicación (navegador) se puede resolver en video chats peer-to-peer o p2p (peer-to-peer, punto a punto) basados ​​en el protocolo WebRTC. Básicamente, un navegador compatible con WebRTC se convierte en una interfaz única para todos los dispositivos de usuario (PC, teléfonos inteligentes, iPads, teléfonos IP, teléfonos móviles etc.) que trabajan con servicios de comunicación.

Es WebRTC el que garantiza la implementación en el navegador de todas las tecnologías que proporcionan comunicaciones en tiempo real. La esencia de los videochats p2p es que los datos multimedia y de texto se transfieren directamente entre los navegadores de los usuarios (peering remoto) sin la participación de un servidor ni programas adicionales. Así, los navegadores no sólo proporcionan acceso a casi todos recursos de información Internet, que se almacenan en servidores, pero también se convierten en un medio de acceso a todos los servicios de comunicación en tiempo real y a los servicios de correo (correo de voz, correo electrónico, SMS, etc.)

Los servidores (servidores de contacto) de video chats p2p están destinados únicamente a registrar usuarios, almacenar datos sobre los usuarios y establecer una conexión (conmutación) entre los navegadores de los usuarios. Los primeros videochats p2p se implementaron utilizando tecnologías flash. Los chats de vídeo Flash p2p se utilizan, por ejemplo, en en las redes sociales. Los chats de vídeo Flash p2p no proporcionan alta calidad transmisión de datos multimedia. Además, para emitir transmisiones de voz y vídeo desde el micrófono y la cámara de vídeo en chats de vídeo flash p2p, es necesario instalar complemento flash en un navegador web.

Pero la nueva generación de servicios de telecomunicaciones incluye comunicaciones web, que utilizan únicamente navegadores y servidores de contacto que admiten protocolos WebRTC y la especificación HTML5 para comunicarse a través de Internet. Cualquier dispositivo de usuario (PC, iPad, teléfonos inteligentes, etc.) equipado con dicho navegador puede proporcionar llamadas de voz y video de alta calidad, así como la transferencia de archivos y mensajes de texto instantáneos.

Así, la nueva tecnología de comunicación web (chats p2p, chats de vídeo) es el protocolo WebRTC. WebRTC junto con HTML5, CSS3 y JavaScript le permiten crear varias aplicaciones web. WebRT está diseñado para organizar comunicaciones web (redes peer-to-peer) en tiempo real utilizando una arquitectura peer-to-peer. Los chats P2P basados ​​en WebRTC proporcionan transferencia de archivos, así como comunicación de texto, voz y video entre usuarios a través de Internet utilizando solo navegadores web sin el uso de complementos y complementos externos en el navegador.

En los chats p2p, el servidor se utiliza únicamente para establecer una conexión p2p entre dos navegadores. Para crear la parte cliente de un chat p2p basado en el protocolo WebRTC se utiliza HTML5, CSS3 y JavaScript. La aplicación cliente interactúa con los navegadores a través de la API WebRTC.

WebRTC se implementa mediante tres API de JavaScript:

  • Conexión RTCPeer;
  • MediaStream(getUserMedia);
  • Canal de datos RTC.

Los navegadores transfieren datos multimedia mediante el protocolo SRTP, que se ejecuta sobre UDP. Dado que NAT crea problemas para los navegadores (clientes) detrás de enrutadores NAT que usan conexiones p2p a través de Internet, STUN se utiliza para evitar los traductores NAT. STUN es un protocolo cliente-servidor que se ejecuta sobre el protocolo de transporte UDP. En los chats p2p, por regla general, se utiliza un servidor STUN público y la información recibida de él se utiliza para una conexión UDP entre dos navegadores si están detrás de NAT.

Ejemplos de implementación de aplicaciones WebRTC (chats p2p, chats web de voz y vídeo):
1. El video chat P2P Bistri (video chat con un clic, chat p2p), basado en WebRTC, se puede abrir en Bistri. Bistri funciona en el navegador sin instalar programas ni complementos adicionales. La esencia del trabajo es la siguiente: abra un video chat p2p usando el enlace especificado, después de registrarse en la interfaz que se abre, invite a socios, luego de la lista de pares clientes seleccione el socio que está en línea y haga clic en "videollamada " botón.

Como resultado, MediaStream (getUserMedia) capturará el micrófono + la cámara web y el servidor intercambiará mensajes de señalización con el socio seleccionado. Después de intercambiar mensajes de señalización, la API PeerConnection crea canales para transmitir transmisiones de voz y video. Además, Bistri transfiere archivos y mensajes de texto instantáneos. En la Fig. 1 muestra una captura de pantalla de la interfaz de video chat p2p de Bistri.


Arroz. 1. Video chat P2P Bistri

2. Twelephone (video chat p2p, chat p2p, SIP Twelephone): esta aplicación cliente está construida sobre la base de HTML5 y WebRTC, que le permite realizar llamadas de voz y video, así como enviar mensajes de texto instantáneos, es decir. Twelephone incluye chat p2p de prueba, video chat y SIP Twelephone. Cabe señalar que Twelephone admite el protocolo SIP y ahora puedes realizar y recibir llamadas de voz y video desde teléfonos SIP utilizando tu cuenta de Twitter como número de teléfono. Además, mensajes de texto puedes ingresar por voz a través del micrófono, y el programa de reconocimiento de voz ingresa el texto en la línea "Enviar un mensaje".

Twelephone es una telefonía web basada en navegador Google Chrome, a partir de la versión 25, sin adicionales software. Twelephone fue desarrollado por Chris Matthieu. El backend de Twelephone está construido sobre Node.js. El servidor (servidor de contacto) se utiliza únicamente para establecer una conexión p2p entre dos navegadores o clientes WebRTC. La aplicación Twelephone no tiene herramientas de autorización propias, sino que está enfocada a conectarse a una cuenta ( cuenta) en Twitter.

En la Fig. 2 muestra una captura de pantalla de la interfaz de video chat p2p de Twelephone.



Arroz. 2. Teléfono P2P

3. Video chat grupal p2p Conversat.io se basa en las últimas tecnologías WebRTC y HTML5. El video chat de Conversat está desarrollado en base a la biblioteca SimpleWebRTC y está diseñado para la comunicación entre hasta 6 pares clientes en una sala (para la comunicación, indique el nombre de la sala común para pares clientes en la línea "Nombre de la conversación"). El video chat P2P Conversat proporciona servicios de comunicación a los usuarios sin registrarse en el servidor de contacto. En la Fig. La Figura 3 muestra una captura de pantalla de la interfaz de video chat de Conversat p2p.



Arroz. 3. Videochat grupal P2P Conversat.io

Para participar en chats de vídeo P2P basados ​​en WebRTC, los usuarios deben tener instalado un navegador que admita el protocolo WebRTC y la especificación HTML5. Actualmente, los navegadores Google Chrome, a partir de la versión 25 y Mozilla Firefox Nightly admite el protocolo WebRTC y la especificación HTML5. Las aplicaciones WebRTC son superiores a las aplicaciones Flash en términos de calidad de transmisión de imagen y sonido.

La mayor parte del material de WebRTC se centra en el nivel de aplicación de codificación y no contribuye a la comprensión de la tecnología. Intentemos profundizar y descubrir cómo se produce la conexión, qué son los descriptores de sesión y los candidatos, por qué se necesitan los servidores STUN y TURN.

Introducción a WebRTC

WebRTC es una tecnología orientada al navegador que le permite conectar dos clientes para la transferencia de datos de video. Las características principales son la compatibilidad con el navegador interno (no hay necesidad de tecnologías implementadas por terceros, como Adobe Flash) y la capacidad de conectar clientes sin el uso de servidores adicionales: conexión de igual a igual (en adelante, p2p).

Establecer una conexión p2p es una tarea bastante difícil, ya que las computadoras no siempre tienen direcciones IP públicas, es decir, direcciones en Internet. Debido a la pequeña cantidad de direcciones IPv4 (y por motivos de seguridad), se desarrolló el mecanismo NAT, que permite crear redes privadas, por ejemplo, para uso doméstico. Muchos enrutadores domésticos ahora admiten NAT y gracias a esto, todos los dispositivos domésticos tienen acceso a Internet, aunque los proveedores de Internet suelen proporcionar una dirección IP. Las direcciones IP públicas son únicas en Internet, pero las privadas no. Por tanto, conectar p2p es difícil.

Para entender esto mejor, considere tres situaciones: ambos nodos están en la misma red (Figura 1), ambos nodos están en redes diferentes (uno privado y el otro público) (Figura 2) y ambos nodos están en diferentes redes privadas con las mismas direcciones IP (Figura 3).

Figura 1: Ambos nodos en la misma red

Figura 2: Nodos en diferentes redes (uno privado, otro público)

Figura 3: Nodos en diferentes redes privadas, pero con direcciones numéricamente iguales

En las figuras anteriores, la primera letra de la notación de dos caracteres indica el tipo de nodo (p = par, r = enrutador). En la primera imagen, la situación es favorable: los nodos de su red están completamente identificados por las direcciones IP de la red y, por lo tanto, pueden conectarse entre sí directamente. En la segunda figura tenemos dos redes diferentes con números de nodos similares. Aquí es donde aparecen los routers (routers), que tienen dos interfaz de red– dentro de su red y fuera de su red. Por eso tienen dos direcciones IP. Los nodos regulares tienen una sola interfaz a través de la cual pueden comunicarse únicamente dentro de su red. Si transmiten datos a alguien fuera de su red, entonces solo usan NAT dentro del enrutador (enrutador) y, por lo tanto, son visibles para otros bajo la dirección IP del enrutador: es de ellos. externo Dirección IP. Entonces el nodo p1 tiene interior PI = 192.168.0.200 Y externo PI = 10.50.200.5 , y la última dirección también será externa a todos los demás nodos de su red. La situación es similar para el nodo p2. Por lo tanto, su comunicación es imposible si sólo se utilizan sus direcciones IP internas (propias). Puede utilizar direcciones externas, es decir, direcciones de enrutador, pero como todos los nodos de la misma red privada tienen la misma dirección externa, esto es bastante difícil. Este problema se puede resolver utilizando el mecanismo NAT.

¿Qué pasará si decidimos conectar nodos a través de sus direcciones internas? Los datos no saldrán de la red. Para mejorar el efecto, puede imaginar la situación que se muestra en la última figura: ambos nodos tienen las mismas direcciones internas. Si los usan para comunicarse, cada nodo se comunicará consigo mismo.

WebRTC resuelve con éxito estos problemas utilizando el protocolo ICE, que, sin embargo, requiere el uso de servidores adicionales (STUN, TURN). Más sobre todo esto a continuación.

Dos fases de WebRTC

Para conectar dos nodos mediante el protocolo WebRTC (o simplemente RTC, si se comunican dos iPhone), es necesario realizar algunos pasos preliminares para establecer la conexión. Esta es la primera fase: establecer una conexión. La segunda fase es la transmisión de datos de vídeo.

Vale la pena decir de inmediato que, aunque la tecnología WebRTC utiliza muchos de varias maneras comunicaciones (TCP y UDP) y tiene conmutación flexible entre ellas, esta tecnología no tiene un protocolo para transmitir datos de conexión. No es de extrañar, ya que conectar dos nodos p2p no es tan fácil. Por lo tanto es necesario tener algunos adicional un método de transmisión de datos que no está relacionado de ninguna manera con WebRTC. Podría ser una transferencia de socket, protocolo HTTP, incluso podría ser protocolo SMTP o Correo Ruso. Este mecanismo de transmisión inicial los datos se llaman señal. No es necesario transmitir mucha información. Todos los datos se transmiten en forma de texto y se dividen en dos tipos: SDP y Ice Candidate. El primer tipo se utiliza para establecer una conexión lógica y el segundo para una conexión física. Más sobre todo esto más adelante, pero por ahora es importante recordar que WebRTC nos dará información que deberá transmitirse a otro nodo. En cuanto transmitamos toda la información necesaria, los nodos podrán conectarse y ya no será necesaria nuestra ayuda. Entonces, el mecanismo de señalización que debemos implementar es por separado, se utilizará sólo cuando está conectado, pero no se utilizará al transmitir datos de vídeo.

Entonces, consideremos la primera fase: la fase de establecimiento de la conexión. Consta de varios puntos. Veamos esta fase primero para el nodo que inicia la conexión y luego para el que está esperando.

  • Iniciador (llamador):
  • Oferta para iniciar la transferencia de datos de vídeo (createOffer)
  • Obteniendo su SDP SDP)
  • Recibiendo a su candidato Ice Candidato Ice)
  • Llamada en espera (llamado):
  • Recibir una transmisión multimedia local (su) y configurarla para su transmisión (getUserMediaStream)
  • Recibir una oferta para iniciar la transferencia de datos de video y crear una respuesta (createAnswer)
  • Recibir su objeto SDP y pasarlo a través del mecanismo de señalización (SDP)
  • Recibir sus objetos candidatos a Ice y pasarlos a través de un mecanismo de señalización (candidato a Ice)
  • Recibir una transmisión multimedia remota (extranjera) y mostrarla en la pantalla (onAddStream)

La única diferencia está en el segundo punto.

A pesar de la aparente complejidad de los pasos, en realidad hay tres: enviar su propio flujo de medios (elemento 1), configurar los parámetros de conexión (elementos 2 a 4) y recibir el flujo de medios de otra persona (elemento 5). El paso más difícil es el segundo, porque consta de dos partes: establecer físico Y lógico conexiones. El primero indica camino, a lo largo del cual deben viajar los paquetes para llegar de un nodo de red a otro. El segundo indica parámetros de vídeo/audio– qué calidad usar, qué códecs usar.

Mentalmente, la etapa createOffer o createAnswer debe estar conectada a las etapas de paso de objetos candidatos SDP y Ice.

Entidades básicas Flujos de medios (MediaStream)

La esencia principal es el flujo de medios, es decir, el flujo de datos de video y audio, imágenes y sonido. Hay dos tipos de flujos de medios: locales y remotos. El local recibe datos de los dispositivos de entrada (cámara, micrófono) y el remoto a través de la red. Por tanto, cada nodo tiene un hilo local y uno remoto. En WebRTC, hay una interfaz MediaStream para transmisiones y también hay una subinterfaz LocalMediaStream específicamente para una transmisión local. En JavaScript sólo puedes encontrar el primero, pero si usas libjingle también puedes encontrar el segundo.

WebRTC tiene una jerarquía bastante confusa dentro de un hilo. Cada flujo puede constar de varias pistas multimedia (MediaTrack), que a su vez pueden constar de varios canales multimedia (MediaChannel). Y también puede haber varios flujos de medios.

Miremos todo en orden. Para ello, tengamos en cuenta algún ejemplo. Digamos que queremos transmitir no sólo un vídeo de nosotros mismos, sino también un vídeo de nuestra mesa, sobre la que hay un papel en el que vamos a escribir algo. Necesitaremos dos vídeos (nosotros + mesa) y un audio (nosotros). Está claro que nosotros y la tabla deberíamos dividirnos en diferentes subprocesos, porque estos datos probablemente dependen poco unos de otros. Por lo tanto, tendremos dos MediaStreams: uno para nosotros y otro para la mesa. El primero contendrá datos de video y audio, y el segundo contendrá solo video (Figura 4).

Figura 4: Dos flujos de medios diferentes. Uno para nosotros, uno para nuestra mesa.

Inmediatamente queda claro que un flujo de medios debe incluir como mínimo la capacidad de contener datos. diferentes tipos- vídeo y audio. Esto se tiene en cuenta en la tecnología y por eso cada tipo de datos se implementa a través de un seguimiento multimedia MediaTrack. La pista multimedia tiene un tipo de propiedad especial, que determina si es vídeo o audio (Figura 5).

Figura 5: Los flujos de medios constan de pistas de medios

¿Cómo sucederá todo en el programa? Crearemos dos flujos de medios. Luego crearemos dos pistas de video y una pista de audio. Tengamos acceso a las cámaras y al micrófono. Digamos a cada pista qué dispositivo usar. Agreguemos una pista de video y audio a la primera transmisión multimedia y una pista de video de otra cámara a la segunda transmisión multimedia.

Pero, ¿cómo distinguimos los flujos de medios en el otro extremo de la conexión? Para hacer esto, cada flujo de medios tiene una propiedad de etiqueta: la etiqueta del flujo, su nombre (Figura 6). Las pistas multimedia tienen la misma propiedad. Aunque a primera vista parece que el vídeo se puede distinguir del sonido de otras formas.

Figura 6: Las secuencias y pistas de medios se identifican mediante etiquetas

Entonces, si las pistas de medios se pueden identificar mediante una etiqueta, ¿por qué necesitamos usar dos flujos de medios para nuestro ejemplo, en lugar de uno? Después de todo, puede transmitir un flujo multimedia, pero utilizar diferentes pistas en él. Hemos llegado a una propiedad importante de los flujos de medios: sincronizar pistas multimedia. Los diferentes flujos de medios no se sincronizan entre sí, pero dentro de cada flujo de medios todas las pistas se juegan simultáneamente.

Por lo tanto, si queremos que nuestras palabras, nuestras emociones faciales y nuestro papel se reproduzcan simultáneamente, entonces vale la pena utilizar un flujo de medios. Si esto no es tan importante, entonces es más rentable utilizar diferentes transmisiones: la imagen será más fluida.

Si es necesario desactivar alguna pista durante la transmisión, puede utilizar la propiedad habilitada de la pista multimedia.

Finalmente, vale la pena pensar en el sonido estéreo. Como sabes, el sonido estéreo son dos sonidos diferentes. Y también deben trasladarse por separado. Para ello se utilizan MediaChannels. Una pista de audio multimedia puede tener muchos canales (por ejemplo, 6 si necesita 5+1 audio). Por supuesto, también hay canales dentro de las pistas de medios. sincronizado. Para el vídeo normalmente se utiliza sólo un canal, pero se pueden utilizar varios, por ejemplo, para superponer publicidad.

Para resumir: Usamos un flujo de medios para transmitir datos de video y audio. Dentro de cada flujo de medios, los datos se sincronizan. Podemos usar múltiples flujos de medios si no necesitamos sincronización. Dentro de cada flujo multimedia hay dos tipos de pistas multimedia: para vídeo y para audio. Normalmente no hay más de dos pistas, pero puede haber más si necesitas transmitir varios vídeos diferentes (del interlocutor y su mesa). Cada pista puede constar de varios canales, que normalmente se utilizan sólo para sonido estéreo.

En la situación de video chat más simple, tendremos un flujo de medios local, que constará de dos pistas: una pista de video y una pista de audio, cada una de las cuales constará de un canal principal. La pista de vídeo es responsable de la cámara, la pista de audio es del micrófono y el flujo de medios es el contenedor de ambos.

Descriptor de sesión (SDP)

Diferentes computadoras siempre tendrán diferentes cámaras, micrófonos, tarjetas de video y otros equipos. Hay muchas opciones que tienen. Todo esto debe coordinarse para la transferencia multimedia de datos entre dos nodos de la red. WebRTC hace esto automáticamente y crea objeto especial– Descriptor de sesión SDP. Pase este objeto a otro nodo y se podrán transferir los datos multimedia. Sólo que todavía no hay conexión con otro nodo.

Para ello se utiliza cualquier mecanismo de señalización. SDP se puede transmitir a través de enchufes, por una persona (infórmeselo a otro nodo por teléfono) o por correo ruso. Todo es muy simple: se le entregará un SDP ya preparado y deberá enviarlo. Y cuando lo reciba del otro lado, transfiéralo al departamento de WebRTC. El descriptor de sesión se almacena como texto y se puede cambiar en sus aplicaciones, pero generalmente esto no es necesario. Por ejemplo, al conectar una computadora de escritorio ↔ un teléfono, a veces es necesario forzar la selección del códec de audio deseado.

Normalmente, al establecer una conexión, debe especificar algún tipo de dirección, como una URL. Esto no es necesario aquí, ya que a través del mecanismo de señalización tú mismo enviarás los datos a su destino. Para indicarle a WebRTC que queremos establecer una conexión p2p, debemos llamar a la función createOffer. Después de llamar a esta función y especificar una devolución de llamada especial 'a, se creará un objeto SDP y se pasará a la misma devolución de llamada. Todo lo que se requiere de usted es transferir este objeto a través de la red a otro nodo (interlocutor). Después de esto, los datos llegarán al otro extremo a través del mecanismo de señalización, es decir, este objeto SDP. Este descriptor de sesión es ajeno a este nodo y, por lo tanto, contiene información útil. Recibir este objeto es una señal para iniciar la conexión. Por lo tanto, debe aceptar esto y llamar a la función createAnswer. Es un análogo completo de createOffer. Nuevamente, el descriptor de la sesión local se pasará a su devolución de llamada y será necesario volver a pasarlo a través del mecanismo de señalización.

Vale la pena señalar que puede llamar a la función createAnswer solo después de recibir el objeto SDP de otra persona. ¿Por qué? Porque el objeto SDP local que se generará al llamar a createAnswer debe depender del objeto SDP remoto. Sólo en este caso será posible coordinar la configuración de su vídeo con la configuración de su interlocutor. Además, no debe llamar a createAnswer y createOffer antes de recibir la transmisión de medios local; no tendrán nada que escribir en el objeto SDP.

Dado que WebRTC tiene la capacidad de editar un objeto SDP, después de recibir un descriptor local es necesario instalarlo. Puede parecer un poco extraño que necesitemos transferir a WebRTC lo que él mismo nos dio, pero ese es el protocolo. Cuando se recibe una manija remota, también se debe instalar. Por lo tanto, debe instalar dos descriptores en un nodo: el suyo y el de otra persona (es decir, local y remoto).

Después de este apretones de manos Los nodos conocen los deseos de los demás. Por ejemplo, si el nodo 1 admite los códecs A y B, y el nodo 2 admite los códecs B y C, entonces, dado que cada nodo conoce sus propios descriptores y los del otro, ambos nodos elegirán el códec B (Figura 7). La lógica de conexión ahora está establecida y se pueden transmitir flujos de medios, pero hay otro problema: los nodos todavía están conectados solo mediante un mecanismo de señalización.


Figura 7: Negociación de códec

candidato de hielo

La tecnología WebRTC intenta confundirnos con su nueva metodología. Al establecer una conexión, no se especifica la dirección del nodo al que se desea conectar. Instalado primero lógico conexión, no físico, aunque siempre se hizo lo contrario. Pero esto no nos parecerá extraño si no olvidamos que estamos utilizando un mecanismo de señalización de terceros.

Entonces, la conexión ya se ha establecido (conexión lógica), pero aún no existe una ruta por la cual los nodos de la red puedan transmitir datos. No es tan simple, pero comencemos simple. Deje que los nodos estén en la misma red privada. Como ya sabemos, pueden conectarse fácilmente entre sí utilizando sus direcciones IP internas (o quizás algunas otras, si no se utiliza TCP/IP).

A través de alguna devolución de llamada 'y WebRTC nos informa de los objetos candidatos de Ice. También vienen en forma de texto y, al igual que los descriptores de sesión, simplemente deben enviarse a través de un mecanismo de señalización. Si el descriptor de sesión contenía información sobre nuestra configuración a nivel de cámara y micrófono, entonces los candidatos contienen información sobre nuestra ubicación en la red. Páselos a otro nodo y podrá conectarse físicamente con nosotros, y como ya tiene un descriptor de sesión, lógicamente podrá conectarse y los datos "fluirán". Si recuerda enviarnos su objeto candidato, es decir, información sobre dónde se encuentra él en la red, podremos conectarnos con él. Observemos aquí una diferencia más con la clásica interacción cliente-servidor. La comunicación con el servidor HTTP se produce según el esquema de solicitud-respuesta, el cliente envía datos al servidor, quien los procesa y los envía a través de la dirección especificada en el paquete de solicitud. En WebRTC necesitas saber dos direcciones y conectarlos por ambos lados.

La diferencia con los descriptores de sesión es que solo es necesario instalar candidatos remotos. La edición aquí está prohibida y no puede aportar ningún beneficio. En algunas implementaciones de WebRTC, los candidatos deben instalarse solo después de que se hayan configurado los descriptores de sesión.

¿Por qué solo había un descriptor de sesión pero podía haber muchos candidatos? Porque la ubicación en la red se puede determinar no solo por su dirección IP interna, sino también por la dirección externa del enrutador, y no necesariamente solo una, así como por las direcciones de los servidores TURN. El resto del párrafo se dedicará a una discusión detallada de los candidatos y cómo conectar nodos de diferentes redes privadas.

Entonces, dos nodos están en la misma red (Figura 8). ¿Cómo identificarlos? Usando direcciones IP. Ninguna otra manera. Es cierto que aún puedes utilizar diferentes transportes (TCP y UDP) y diferentes puertos. Esta es la información contenida en el objeto candidato: IP, PUERTO, TRANSPORTE y algunos otros. Utilicemos, por ejemplo, el transporte UDP y el puerto 531.

Figura 8: Dos nodos están en la misma red

Luego, si estamos en el nodo p1, WebRTC nos dará dicho objeto candidato: . Este no es un formato exacto, sólo un diagrama. Si estamos en el nodo p2, entonces el candidato es. A través del mecanismo de señalización, p1 recibirá el candidato de p2 (es decir, la ubicación del nodo p2, es decir, su IP y PUERTO). Entonces p1 puede conectarse a p2 directamente. Más correctamente, p1 enviará datos a 10.50.150.3:531 con la esperanza de que llegue a p2. No importa si esta dirección pertenece al nodo p2 o a algún intermediario. Lo único importante es que los datos se enviarán a través de esta dirección y podrán llegar a p2.

Mientras los nodos estén en la misma red, todo es simple y fácil: cada nodo tiene solo un objeto candidato (siempre es decir el suyo, es decir, su ubicación en la red). Pero habrá muchos más candidatos cuando los nodos estén en diferente redes.

Pasemos a un caso más complejo. Un nodo estará ubicado detrás del enrutador (más precisamente, detrás de NAT) y el segundo nodo estará ubicado en la misma red que este enrutador (por ejemplo, en Internet) (Figura 9).

Figura 9: Un nodo está detrás de NAT, el otro no

Este caso tiene una solución particular al problema, que consideraremos ahora. Enrutador doméstico normalmente contiene una tabla NAT. Este es un mecanismo especial diseñado para permitir que los nodos dentro de la red privada del enrutador accedan, por ejemplo, a sitios web.

Supongamos que el servidor web está conectado a Internet directamente, es decir, tiene una dirección IP* pública. Sea este el nodo p2. El nodo p1 (cliente web) envía una solicitud a la dirección 10.50.200.10. Primero, los datos van al enrutador r1, o más bien a su interior interfaz 192.168.0.1. Después de lo cual, el enrutador recuerda la dirección de origen (dirección p1) y la ingresa en una tabla NAT especial, luego cambia la dirección de origen a la suya propia (p1 → r1). Además, a mi manera externo interfaz, el enrutador envía datos directamente al servidor web p2. El servidor web procesa los datos, genera una respuesta y la devuelve. Envía r1 al enrutador, ya que está en la dirección de retorno (el enrutador reemplazó la dirección por la suya). El enrutador recibe los datos, mira la tabla NAT y reenvía los datos al nodo p1. El enrutador actúa aquí como intermediario.

¿Qué pasa si varios nodos de la red interna acceden simultáneamente a la red externa? ¿Cómo sabrá el enrutador a quién enviar la respuesta? Este problema se resuelve usando puertos. Cuando un enrutador reemplaza la dirección del host por la suya propia, también reemplaza el puerto. Si dos nodos acceden a Internet, el enrutador reemplaza sus puertos de origen con diferente. Luego, cuando el paquete del servidor web regresa al enrutador, el enrutador entenderá por el puerto a quién está asignado el paquete. Ejemplo a continuación.

Volvamos a la tecnología WebRTC, o más precisamente, a su parte que utiliza el protocolo ICE (de ahí los candidatos Ice). El nodo p2 tiene un candidato (su ubicación en la red es 10.50.200.10), y el nodo p1, que está ubicado detrás del enrutador con NAT, tendrá dos candidatos: local (192.168.0.200) y candidato de enrutador (10.50.200.5). El primero no es útil, pero se genera de todos modos, ya que WebRTC aún no sabe nada sobre el nodo remoto; puede que esté o no en la misma red. El segundo candidato nos vendrá muy bien y, como ya sabemos, el puerto (para pasar por NAT) jugará un papel importante.

Se genera una entrada en la tabla NAT solo cuando los datos salen de la red interna. Por lo tanto, el nodo p1 debe transmitir los datos primero y solo después los datos del nodo p2 pueden llegar al nodo p1.

En la practica ambos nodos estará detrás de NAT. Para crear una entrada en la tabla NAT de cada enrutador, los hosts deben enviar algo al host remoto, pero esta vez ni el primero puede llegar al segundo ni viceversa. Esto se debe al hecho de que los nodos no conocen sus direcciones IP externas y no tiene sentido enviar datos a direcciones internas.

Sin embargo, si se conocen las direcciones externas, la conexión se establecerá fácilmente. Si el primer nodo envía datos al enrutador del segundo nodo, el enrutador lo ignorará, ya que su tabla NAT aún está vacía. Sin embargo, en el enrutador del primer nodo apareció una entrada necesaria en la tabla NAT. Si ahora el segundo nodo envía datos al enrutador del primer nodo, entonces el enrutador los transferirá exitosamente al primer nodo. Ahora la tabla NAT del segundo enrutador también contiene los datos necesarios.

El problema es que para averiguar su dirección IP externa, necesita un nodo ubicado en red compartida. Para solucionar este problema se utilizan servidores adicionales que están conectados directamente a Internet. Con su ayuda también se crean entradas preciadas en la tabla NAT.

Servidores STUN y TURN

Al inicializar WebRTC, debe especificar los servidores STUN y TURN disponibles, a los que en adelante llamaremos servidores ICE. Si no se especifican servidores, solo podrán conectarse los nodos de la misma red (conectados a ella sin NAT). Inmediatamente vale la pena señalar que para las redes 3g el uso de servidores TURN es obligatorio.

ATURDIR servidor es simplemente un servidor en Internet que devuelve una dirección de remitente, es decir, la dirección del nodo del remitente. El host detrás del enrutador contacta al servidor STUN para atravesar NAT. El paquete que llegó al servidor STUN contiene la dirección de origen: la dirección del enrutador, es decir, la dirección externa de nuestro nodo. Esta es la dirección STUN que devuelve el servidor. Así, el nodo recibe su dirección IP externa y el puerto a través del cual es accesible desde la red. A continuación, WebRTC utiliza esta dirección para crear un candidato adicional (dirección y puerto del enrutador externo). Ahora hay una entrada en la tabla NAT del enrutador que permite que los paquetes enviados al enrutador en el puerto requerido lleguen a nuestro nodo.

Veamos este proceso con un ejemplo.

Ejemplo (operación del servidor STUN)

El servidor STUN se indicará con s1. El enrutador, como antes, pasa por r1 y el nodo pasa por p1. También necesitarás monitorear la tabla NAT; la designaremos como r1_nat. Además, esta tabla suele contener muchos registros de diferentes nodos de la subred; no se proporcionarán.

Entonces, al principio tenemos una tabla vacía r1_nat.

Tabla 2: Encabezado del paquete

El nodo p1 envía este paquete al enrutador r1 (no importa cómo, diferentes subredes pueden usar diferentes tecnologías). El enrutador debe reemplazar la dirección de origen Src IP, ya que la dirección especificada en el paquete obviamente no es adecuada para una subred externa; además, las direcciones de ese rango están reservadas y ni una sola dirección en Internet tiene esa dirección. El enrutador realiza una sustitución en el paquete y crea nueva entrada en tu tabla r1_nat. Para ello, necesita encontrar un número de puerto. Recuerde que dado que varios hosts dentro de una subred pueden acceder a una red externa, la tabla NAT debe almacenar información adicional, para que el enrutador pueda determinar cuál de estos varios nodos está destinado al paquete de retorno del servidor. Deje que el enrutador abra el puerto 888.

Encabezado del paquete modificado:

Tabla 4: La tabla NAT se ha actualizado con una nueva entrada

Aquí la dirección IP y el puerto de la subred son exactamente los mismos que los del paquete original. De hecho, al realizar una devolución de datos, debemos tener una forma de restaurarlos por completo. La dirección IP de la red externa es la dirección del enrutador y el puerto ha cambiado al inventado por el enrutador.

El puerto real en el que el nodo p1 acepta la conexión es, por supuesto, 35777, pero el servidor envía datos a ficticio puerto 888, que el enrutador cambiará al 35777 real.

Entonces, el enrutador reemplazó la dirección de origen y el puerto en el encabezado del paquete y agregó una entrada a la tabla NAT. Ahora el paquete se envía a través de la red al servidor, es decir, al nodo s1. En la entrada, s1 tiene el siguiente paquete:

Origen IP Origen PUERTO Destino IP Destino PUERTO
10.50.200.5 888 12.62.100.200 6000

Tabla 5: Paquete recibido por el servidor STUN

En total, el servidor STUN sabe que recibió un paquete de la dirección 10.50.200.5:888. Ahora el servidor devuelve esta dirección. Vale la pena detenerse aquí y echar otro vistazo a lo que acabamos de ver. Las tablas anteriores son un fragmento de encabezamiento paquete, en absoluto de él contenido. No hablamos sobre el contenido, ya que no es tan importante: de alguna manera se describe en el protocolo STUN. Ahora consideraremos, además del título, el contenido. Será simple y contendrá la dirección del enrutador: 10.50.200.5:888, aunque la tomamos de encabezamiento paquete. Esto no se hace con frecuencia; a los protocolos generalmente no les importa la información sobre las direcciones de los nodos; sólo es importante que los paquetes se entreguen a su destino previsto. Aquí estamos ante un protocolo que establece una ruta entre dos nodos.

Ahora tenemos un segundo paquete que va en la dirección opuesta:

Tabla 7: El servidor STUN envía un paquete con este contenido

Luego, el paquete viaja a través de la red hasta llegar a la interfaz externa del enrutador r1. El enrutador comprende que el paquete no está destinado a él. ¿Cómo entiende esto? Esto sólo lo puede determinar el puerto. No utiliza el puerto 888 para fines personales, sino que lo utiliza para el mecanismo NAT. Por lo tanto, el enrutador mira esta tabla. Mira la columna PUERTO externo y busca una línea que coincida con el PUERTO de destino del paquete entrante, es decir, 888.

IP interna PUERTO interno IP externa PUERTO externo
192.168.0.200 35777 10.50.200.5 888

Tabla 8: Tabla NAT

Tenemos suerte de que exista esa línea. Si no tuviéramos suerte, el paquete simplemente sería descartado. Ahora necesita comprender qué nodo de la subred debe enviar este paquete. No hay que apresurarse, recordemos nuevamente la importancia de los puertos en este mecanismo. Al mismo tiempo, dos nodos de la subred podrían enviar solicitudes a la red externa. Luego, si al enrutador se le ocurrió el puerto 888 para el primer nodo, para el segundo se le ocurrió el puerto 889. Supongamos que esto sucedió, es decir, la tabla r1_nat se ve así:

Tabla 10: El enrutador reemplaza la dirección del receptor

Origen IP Origen PUERTO Destino IP Destino PUERTO
12.62.100.200 6000 192.168.0.200 35777

Tabla 11: El enrutador cambió la dirección del receptor

El paquete llega exitosamente al nodo p1 y, al observar el contenido del paquete, el nodo aprende acerca de su dirección IP externa, es decir, la dirección del enrutador en la red externa. También conoce el puerto por el que pasa el enrutador a través de NAT.

¿Que sigue? ¿De qué sirve todo esto? Un beneficio es una entrada en la tabla r1_nat. Si ahora alguien envía un paquete con el puerto 888 al enrutador r1, el enrutador reenviará este paquete al nodo p1. Esto creó un pequeño pasaje estrecho hacia el nodo oculto p1.

Del ejemplo anterior puedes hacerte una idea de cómo funciona NAT y la esencia de un servidor STUN. En general, el mecanismo ICE y los servidores STUN/TURN están destinados precisamente a superar las restricciones NAT.

Entre el nodo y el servidor puede haber no un enrutador, sino varios. En este caso, el nodo recibirá la dirección del enrutador que sea el primero en acceder a la misma red que el servidor. En otras palabras, obtendremos la dirección del enrutador conectado al servidor STUN. Para la comunicación p2p, esto es exactamente lo que necesitamos, si no olvidamos el hecho de que cada enrutador agregará la línea que necesitamos a la tabla NAT. Por lo tanto, el camino de regreso volverá a ser igual de sencillo.

El servidor TURN es un servidor STUN mejorado. De aquí deberíamos deducir inmediatamente que cualquier servidor TURN también puede funcionar como servidor STUN. Sin embargo, también hay ventajas. Si la comunicación p2p es imposible (como, por ejemplo, en redes 3g), entonces el servidor cambia al modo de retransmisión, es decir, funciona como intermediario. Por supuesto, entonces no estamos hablando de ningún p2p, pero fuera del mecanismo ICE, los nodos piensan que se están comunicando directamente.

¿En qué casos es necesario un servidor TURN? ¿Por qué no hay suficiente servidor STUN? El caso es que existen varios tipos de NAT. Reemplazan la dirección IP y el puerto de la misma manera, pero algunos de ellos tienen incorporada protección adicional contra la "falsificación". Por ejemplo, en simétrico La tabla NAT almacena 2 parámetros más: IP y puerto del host remoto. Un paquete de la red externa pasa a través de NAT a la red interna solo si la dirección de origen y el puerto coinciden con los registrados en la tabla. Por lo tanto, el truco con el servidor STUN falla: la tabla NAT almacena la dirección y el puerto del servidor STUN y, cuando el enrutador recibe un paquete del interlocutor WebRTC, lo descarta porque está "falsificado". No provino del servidor STUN.

Por lo tanto, se necesita un servidor TURN en el caso de que ambos interlocutores estén detrás simétrico NAT (cada uno por su lado).

Breve resumen

Aquí hay algunas afirmaciones sobre las entidades WebRTC que siempre debes tener en cuenta. Se describen en detalle arriba. Si alguna de las afirmaciones no le parece del todo clara, vuelva a leer los párrafos pertinentes.

  • flujo de medios
    • Los datos de vídeo y audio se empaquetan en flujos de medios.
    • Las transmisiones multimedia sincronizan las pistas multimedia que componen
    • Diferentes flujos de medios no están sincronizados entre sí.
    • Las transmisiones de medios pueden ser locales y remotas, la local generalmente está conectada a una cámara y un micrófono, las remotas reciben datos de la red en forma cifrada.
    • Hay dos tipos de pistas multimedia: de vídeo y de audio.
    • Las pistas multimedia tienen la capacidad de activarse o desactivarse
    • Las pistas de medios constan de canales de medios.
    • Las pistas multimedia sincronizan los canales multimedia que componen
    • Los flujos de medios y las pistas de medios tienen etiquetas por las que se pueden distinguir
  • identificador de sesión
    • El descriptor de sesión se utiliza para conectar lógicamente dos nodos de red.
    • El descriptor de sesión almacena información sobre formas disponibles Codificación de datos de vídeo y audio.
    • WebRTC utiliza un mecanismo de señalización externo: la tarea de reenviar descriptores de sesión (sdp) recae en la aplicación.
    • El mecanismo de conexión lógica consta de dos etapas: oferta (oferta) y respuesta (respuesta).
    • La generación de un descriptor de sesión es imposible sin utilizar un flujo de medios local en el caso de una oferta y es imposible sin utilizar un descriptor de sesión remoto en el caso de una respuesta.
    • El descriptor resultante debe entregarse a la implementación WebRTC, y no importa si este descriptor se recibe de forma remota o local desde la misma implementación WebRTC.
    • Es posible editar ligeramente el descriptor de sesión.
  • Candidatos
    • El candidato de hielo es la dirección de un nodo en la red.
    • La dirección del nodo puede ser la suya o puede ser la dirección de un enrutador o servidor TURN.
    • Siempre hay muchos candidatos.
    • El candidato consta de una dirección IP, puerto y tipo de transporte (TCP o UDP)
    • Los candidatos se utilizan para establecer una conexión física entre dos nodos en una red.
    • Los candidatos también deben ser enviados a través de un mecanismo de señalización.
    • Los candidatos también deben pasar a implementaciones WebRTC, pero solo a las remotas.
    • En algunas implementaciones de WebRTC, los candidatos solo se pueden transmitir después de que se haya establecido un descriptor de sesión.
  • ATURDIMIENTO/GIRO/HIELO/NAT
    • NAT es un mecanismo para proporcionar acceso a una red externa.
    • Los enrutadores domésticos admiten una tabla NAT especial
    • El enrutador reemplaza las direcciones en los paquetes: la dirección de origen por la suya propia, si el paquete va a una red externa, y la dirección del receptor por la dirección del host en la red interna, si el paquete proviene de una red externa.
    • Para proporcionar acceso multicanal a una red externa, NAT utiliza puertos
    • ICE - Motor transversal NAT
    • Servidores STUN y TURN: servidores asistentes para el recorrido NAT
    • El servidor STUN le permite crear las entradas necesarias en la tabla NAT y también devuelve la dirección externa del host.
    • El servidor TURN generaliza el mecanismo STUN y lo hace funcionar siempre.
    • En el peor de los casos, el servidor TURN se utiliza como intermediario (retransmisión), es decir, p2p se convierte en una conexión cliente-servidor-cliente.

Hoy en día, WebRTC es la tecnología más popular para la transmisión de audio y vídeo en navegadores. Las tecnologías conservadoras, como HTTP Streaming y Flash, son más adecuadas para distribuir contenido grabado (vídeo bajo demanda) y son significativamente inferiores a WebRTC en términos de transmisiones en tiempo real y en línea, es decir, donde se requiere una latencia de vídeo mínima para permitir a los espectadores ver lo que sucede “en vivo”.

La posibilidad de una comunicación de alta calidad en tiempo real proviene de la propia arquitectura WebRTC, donde se utiliza el protocolo UDP para transportar transmisiones de video, que es la base estándar para transmitir video con retrasos mínimos y se usa ampliamente en sistemas de comunicación en tiempo real.

La latencia de la comunicación es importante en los sistemas de transmisión en línea, seminarios web y otras aplicaciones que requieren comunicación interactiva con la fuente de video, los usuarios finales y requieren una solución.

Otra buena razón para probar WebRTC es que definitivamente es una tendencia. Hoy todos los Android Navegador Chrome admite esta tecnología, lo que garantiza millones de dispositivos listos para ver la transmisión sin instalar ningún software o configuración adicional.

Para probar la tecnología WebRTC en acción y ejecutar un simple transmisión en línea, utilizamos el software de servidor Flashphoner WebRTC Media & Broadcasting Server. Las características establecen la capacidad de transmitir secuencias WebRTC en modo uno a muchos, así como soporte para cámaras IP y sistemas de videovigilancia a través del protocolo RTSP; En esta revisión nos centraremos en las transmisiones web-web y sus características.

Instalación del servidor de radiodifusión y medios WebRTC

Porque para sistemas windows no había una versión de servidor y no quería instalar una máquina virtual como VMWare+Linux, así que podía probar transmisiones en línea en casa. computadora con windows No funciono. Para ahorrar tiempo, decidimos tomar un ejemplo de alojamiento en la nube como este:

Era Centos x86_64 versión 6.5 sin ningún software preinstalado en el centro de datos de Ámsterdam. Así, lo único que tenemos a nuestra disposición es el servidor y el acceso ssh al mismo. Para aquellos que están familiarizados con comandos de consola Linux, la instalación de un servidor WebRTC promete ser simple e indolora. Entonces lo que hicimos:

1. Descargue el archivo:

$wget https://site/download-wcs5-server.tar.gz

2. Desempacar:

$tar -xzf descargar-wcs5-server.tar.gz

3. Instalar:

$cd FlashphonerWebCallServer

Durante la instalación, ingrese la dirección IP del servidor: XXX.XXX.XXX.XXX

4. Active la licencia:

$cd /usr/local/FlashphonerWebCallServer/bin

$./activación.sh

5. Inicie el servidor WCS:

$servicio de inicio del servidor de llamadas web

6. Verifique el registro:

$cola - f /usr/local/FlashphonerWebCallServer/logs/flashphoner_manager.log

7. Verifique que los dos procesos estén implementados:

$ps auxiliar | grep Flashphoner

El proceso de instalación está completo.

Prueba de transmisiones en línea WebRTC

Probar las transmisiones resultó ser una cuestión sencilla. Además del servidor, hay un cliente web, que consta de una docena de archivos Javascript, HTML y CSS y que implementamos en la carpeta /var/www/html durante la etapa de instalación. Lo único que había que hacer era ingresar la dirección IP del servidor en la configuración flashphoner.xml para que el cliente web pudiera establecer una conexión con el servidor a través de HTML5 Websockets. Describamos el proceso de prueba.

1. Abra la página del cliente de prueba index.html en el navegador Chrome:

2. Para comenzar a transmitir, debe hacer clic en el botón "Iniciar" en el medio de la pantalla.
Antes de hacer esto, debe asegurarse de que la cámara web esté conectada y lista para usar. No existen requisitos especiales para la cámara web; por ejemplo, utilizamos una cámara estándar integrada en una computadora portátil con una resolución de 1280x800.

El navegador Chrome definitivamente solicitará acceso a la cámara y al micrófono para que el usuario comprenda que su video se enviará al servidor de Internet y lo permita.

3. La interfaz representa una transmisión exitosa de la transmisión de video desde la cámara al servidor WebRTC. En la esquina superior derecha, un indicador indica que la transmisión va al servidor; en la esquina inferior hay un botón “Detener” para dejar de enviar el video.

Tenga en cuenta el enlace en el cuadro a continuación. Contiene un identificador único para esta transmisión, por lo que cualquiera puede unirse a la visualización. Simplemente abra este enlace en su navegador. Para copiarlo al portapapeles, haga clic en el botón "Copiar".

En aplicaciones reales como seminarios web, conferencias, transmisiones de video en línea o televisión interactiva, los desarrolladores deberán implementar la distribución de este identificador a ciertos grupos de espectadores para que puedan conectarse a las transmisiones deseadas, pero esta ya es la lógica de la aplicación. . WebRTC Media & Broadcasting Server no lo afecta, solo distribuye video.

5. Se establece la conexión y el espectador ve la transmisión en la pantalla. Ahora puede enviar un enlace a otra persona, detener la reproducción o habilitar el modo de pantalla completa usando los controles en la esquina inferior derecha.

Resultados de las pruebas del servidor de transmisión en línea WebRTC

Durante las pruebas, la latencia parecía perfecta. El ping al centro de datos fue de unos 100 milisegundos y el retraso fue invisible a la vista. A partir de aquí, podemos suponer que el retraso real es el mismo 100 más o menos unas pocas decenas de milisegundos para el tiempo de almacenamiento en búfer. En comparación con el video Flash: en tales pruebas, Flash no se comporta tan bien como WebRTC. Entonces, si mueves la mano en una red similar, el movimiento en la pantalla se puede ver solo después de uno o dos segundos.

En cuanto a la calidad, observamos que los cubos a veces se pueden distinguir por sus movimientos. Esto es coherente con la naturaleza del códec VP8 y su objetivo principal: proporcionar comunicación por vídeo en tiempo real con una calidad aceptable y sin retrasos en la comunicación.

El servidor es bastante fácil de instalar y configurar; ejecutarlo no requiere ninguna habilidad seria, excepto el conocimiento de Linux al nivel de un usuario avanzado que puede ejecutar comandos desde la consola a través de ssh y usar editor de texto. Como resultado, logramos configurar una transmisión en línea de uno a muchos entre navegadores. Conectar espectadores adicionales a la transmisión tampoco planteó ningún problema.

La calidad de la transmisión resultó bastante aceptable para seminarios web y transmisiones en línea. Lo único que generó algunas dudas fue la resolución del vídeo. La cámara admite 1280x800, pero la resolución en la imagen de prueba es muy similar a 640x480. Al parecer, es necesario aclarar esta cuestión con los desarrolladores.

Video sobre pruebas transmitidas desde una cámara web.
a través del servidor WebRTC

Las tecnologías para realizar llamadas desde el navegador existen desde hace muchos años: Java, ActiveX, Adobe Flash...En los últimos años ha quedado claro que los complementos y la izquierda maquinas virtuales No destacan por su comodidad (¿por qué debería instalar nada?) y, lo más importante, por su seguridad. ¿Qué hacer? ¡Hay una salida!

Hasta hace poco, las redes IP utilizaban varios protocolos para telefonía IP o vídeo: SIP, el protocolo más común, desapareciendo de escena H.323 y MGCP, Jabber/Jingle (usado en Gtalk), Adobe RTMP* semiabierto y, por supuesto, , cerró Skype. El proyecto WebRTC, iniciado por Google, intenta cambiar la situación en el mundo de la telefonía IP y web, haciendo que todos softphones, incluido Skype. WebRTC no solo implementa todas las capacidades de comunicación directamente dentro del navegador, que ahora está instalado en casi todos los dispositivos, sino que también intenta resolver simultáneamente un problema más general de comunicación entre los usuarios del navegador (intercambio de diversos datos, transmisión de pantalla, colaboración con documentos y mucho más).

WebRTC desde la perspectiva del desarrollador web

Desde el punto de vista de un desarrollador web, WebRTC consta de dos partes principales:

  • control de flujos de medios desde recursos locales (cámara, micrófono o pantalla) computadora local) se implementa mediante el método navigator.getUserMedia, que devuelve un objeto MediaStream;
  • comunicación peer-to-peer entre dispositivos que generan flujos de medios, incluida la definición de métodos de comunicación y su transmisión directa: objetos RTCPeerConnection (para enviar y recibir flujos de audio y video) y RTCDataChannel (para enviar y recibir datos desde el navegador).
qué hacemos?

Descubriremos cómo organizar un simple video chat multiusuario entre navegadores basado en WebRTC utilizando sockets web. Empezaremos a experimentar en Chrome/Chromium, como los navegadores más avanzados en términos de WebRTC, aunque Firefox 22, lanzado el 24 de junio, casi los ha alcanzado. Hay que decir que el estándar aún no se ha adoptado y la API puede cambiar de una versión a otra. Todos los ejemplos se probaron en Chromium 28. Para simplificar, no supervisaremos la limpieza del código ni la compatibilidad entre navegadores.

Transmisión de medios

El primer y más simple componente WebRTC es MediaStream. Le da al navegador acceso a transmisiones multimedia desde la cámara y el micrófono de la computadora local. En Chrome, para esto es necesario llamar a la función navigator.webkitGetUserMedia() (dado que el estándar aún no está finalizado, todas las funciones vienen con un prefijo, y en Firefox la misma función se llama navigator.mozGetUserMedia()). Cuando lo llame, se le pedirá al usuario que permita el acceso a la cámara y al micrófono. Será posible continuar la llamada sólo después de que el usuario dé su consentimiento. Los parámetros del flujo multimedia requerido y dos funciones de devolución de llamada se pasan como parámetros a esta función: la primera se llamará si se obtiene acceso a la cámara/micrófono con éxito, la segunda, en caso de error. Primero, creemos un archivo HTML rtctest1.html con un botón y un elemento:

WebRTC: primer vídeo de introducción (alto: 240 px; ancho: 320 px; borde: 1 px gris sólido;) getUserMedia

Microsoft CU-RTC-Web

Microsoft no sería Microsoft si no respondiera inmediatamente a la iniciativa de Google lanzando su propia opción no estándar incompatible llamada CU-RTC-Web (html5labs.interoperabilitybridges.com/cu-rtc-web/cu-rtc-web. htm). Aunque la proporción de IE, ya pequeña, sigue disminuyendo, el número de usuarios de Skype da a Microsoft la esperanza de desplazar a Google, y se puede suponer que este estándar en particular se utilizará en el navegador. Versiones de Skype. El estándar de Google se centra principalmente en la comunicación entre navegadores; Al mismo tiempo, la mayor parte del tráfico de voz aún permanece en la red telefónica regular, y se necesitan puertas de enlace entre esta y las redes IP no sólo para facilitar su uso o una distribución más rápida, sino también como un medio de monetización que permitirá a más jugadores desarrollarlos. La aparición de otro estándar no sólo puede llevar a los desarrolladores a la desagradable necesidad de soportar dos tecnologías incompatibles a la vez, sino que en el futuro también puede brindar al usuario una opción más amplia de posibles funcionalidades y soluciones técnicas disponibles. Espera y verás.

Habilitar la transmisión local

Dentro de las etiquetas de nuestro archivo HTML, declaremos una variable global para el flujo de medios:

Var localStream = nulo;

El primer parámetro del método getUserMedia debe especificar los parámetros del flujo de medios solicitado; por ejemplo, simplemente habilite audio o video:

Var streamConstraints = ("audio": verdadero, "vídeo": verdadero); // Solicitar acceso tanto a audio como a vídeo

O especifique parámetros adicionales:

Var streamConstraints = ( "audio": true, "video": ( "obligatorio": ( "maxWidth": "320", "maxHeight": "240", "maxFrameRate": "5"), "opcional": ) );

El segundo parámetro del método getUserMedia debe pasarse a la función de devolución de llamada, que se llamará si tiene éxito:

Función getUserMedia_success(stream) ( console.log("getUserMedia_success():", stream); localVideo1.src = URL.createObjectURL(stream); // Conecta el flujo de medios al elemento HTML localStream = stream; // y guárdalo en una variable global para uso posterior)

El tercer parámetro es una función de devolución de llamada, un controlador de errores que se llamará en caso de error.

Función getUserMedia_error(error) ( console.log("getUserMedia_error():", error); )

La llamada real al método getUserMedia es una solicitud de acceso al micrófono y a la cámara cuando se presiona el primer botón.

Función getUserMedia_click() ( console.log("getUserMedia_click()"); navigator.webkitGetUserMedia(streamConstraints, getUserMedia_success, getUserMedia_error); )

No es posible acceder a una transmisión multimedia desde un archivo abierto localmente. Si intentamos hacer esto, obtendremos el error:

NavigatorUserMediaError (código: 1, PERMISSION_DENIED: 1)"

Subimos el archivo resultante al servidor, lo abrimos en el navegador y, en respuesta a la solicitud que aparece, permitimos el acceso a la cámara y al micrófono.

Puede seleccionar los dispositivos a los que Chrome tendrá acceso en Configuración, Mostrar enlace de configuración avanzada, sección Privacidad, botón Contenido. En los navegadores Firefox y Opera, los dispositivos se seleccionan de una lista desplegable directamente cuando se permite el acceso.

Cuando se utiliza el protocolo HTTP, se solicitará permiso cada vez que se acceda al flujo multimedia después de que se haya cargado la página. Cambiar a HTTPS le permitirá mostrar la solicitud una vez, solo la primera vez que acceda al flujo multimedia.

Observe el círculo pulsante en el ícono de marcador y el ícono de la cámara en el lado derecho de la barra de direcciones:

Conexión de medios RTC

RTCMediaConnection es un objeto diseñado para establecer y transmitir flujos de medios a través de la red entre participantes. Además, este objeto es responsable de generar una descripción de sesión de medios (SDP), obteniendo información sobre los candidatos ICE para atravesar NAT o cortafuegos(local y usando STUN) e interacción con el servidor TURN. Cada participante debe tener una RTCMediaConnection por conexión. Los flujos de medios se transmiten mediante el protocolo SRTP cifrado.

TURNO servidores

Hay tres tipos de candidatos ICE: host, srflx y retransmisión. El host contiene información recibida localmente, srflx: cómo se ve el nodo para un servidor externo (STUN) y retransmisión: información para enviar el tráfico a través del servidor TURN. Si nuestro nodo está detrás de NAT, los candidatos a host contendrán direcciones locales y será inútil, los candidatos srflx solo ayudarán con ciertos tipos de NAT y la retransmisión será la última esperanza para pasar el tráfico a través de un servidor intermedio.

Ejemplo de un candidato ICE de tipo host, con dirección 192.168.1.37 y puerto udp/34022:

A=candidato:337499441 2 udp 2113937151 192.168.1.37 34022 tipo host generación 0

Formato general para especificar servidores STUN/TURN:

Var servidores = ( "iceServers": [ ( "url": "stun:stun.stunprotocol.org:3478" ), ( "url": "turn:user@host:port", "credential": "contraseña" ) ]);

Hay muchos servidores STUN públicos en Internet. Hay una lista larga, por ejemplo. Desafortunadamente, resuelven muy pocos problemas. Prácticamente no existen servidores TURN públicos, a diferencia de STUN. Esto se debe al hecho de que el servidor TURN pasa a través de flujos de medios que pueden cargar significativamente tanto el canal de red como el propio servidor. Por lo tanto, la forma más sencilla de conectarse a los servidores TURN es instalarlo usted mismo (obviamente, necesitará una IP pública). De todos los servidores, en mi opinión, el mejor es el rfc5766-turn-server. Incluso hay una imagen lista para usar para Amazon EC2.

Con TURN, no todo es tan bueno como nos gustaría, pero se está desarrollando activamente y me gustaría esperar que después de un tiempo WebRTC, si no iguale a Skype en términos de calidad de paso a través de traducción de direcciones (NAT) y firewalls. , al menos se nota que se acercará.

RTCMediaConnection requiere un mecanismo adicional para intercambiar información de control para establecer una conexión; aunque genera estos datos, no los transmite y la transmisión a otros participantes debe realizarse por separado.


La elección del método de transferencia recae en el desarrollador, al menos manualmente. Tan pronto como se realice el intercambio de datos necesarios, RTCMediaConnection instalará automáticamente los flujos de medios (si es posible, por supuesto).

modelo oferta-respuesta

Para establecer y cambiar flujos de medios, se utilizan el modelo de oferta/respuesta (descrito en RFC3264) y el SDP (Protocolo de descripción de sesión). También son utilizados por el protocolo SIP. En este modelo, hay dos agentes: Oferente - el que genera la descripción SDP de la sesión para crear una nueva o modificar una existente (Oferta SDP), y Respondedor - el que recibe la descripción SDP de la sesión de otro agente y responde con su propia descripción de sesión (Respuesta SDP). Al mismo tiempo, la especificación requiere un protocolo de nivel superior (por ejemplo, SIP o el suyo sobre web sockets, como en nuestro caso), que se encarga de transmitir SDP entre agentes.

Qué datos se deben pasar entre dos RTCMediaConnections para que puedan establecer secuencias de medios con éxito:

  • El primer participante que inicia la conexión forma una Oferta en la que transmite una estructura de datos SDP (el mismo protocolo se utiliza para el mismo propósito en SIP) que describe las posibles características del flujo de medios que está a punto de comenzar a transmitir. Este bloque de datos debe transferirse al segundo participante. El segundo participante forma una Respuesta, con su SDP, y se la envía al primero.
  • Tanto el primer como el segundo participante realizan el procedimiento de determinación de posibles candidatos a ICE, con la ayuda del cual el segundo participante puede transmitirles un flujo de medios. A medida que se identifican los candidatos, la información sobre ellos debe transmitirse a otro participante.

Oferta de formación

Para generar una Oferta, necesitamos dos funciones. Se llamará al primero si se forma con éxito. El segundo parámetro del método createOffer() es una función de devolución de llamada que se llama en caso de un error durante su ejecución (siempre que el hilo local ya esté disponible).

Además, se necesitan dos controladores de eventos: onicecandidate cuando se define un nuevo candidato ICE y onaddstream cuando se conecta un flujo de medios desde el lado lejano. Volvamos a nuestro archivo. Agreguemos otro al HTML después de las líneas con elementos:

crearoferta

Y después de la línea con el elemento (para el futuro):


También al comienzo del código JavaScript declararemos una variable global para RTCPeerConnection:

Varpc1;

Al llamar al constructor RTCPeerConnection, debe especificar servidores STUN/TURN. Para obtener más información sobre ellos, consulte la barra lateral; Siempre que todos los participantes estén en la misma red, no son obligatorios.

Servidores var = nulo;

Parámetros para preparar la Oferta SDP

Var ofertaConstraints = ();

El primer parámetro del método createOffer() es una función de devolución de llamada que se llama tras la formación exitosa de una oferta.

Función pc1_createOffer_success(desc) ( console.log("pc1_createOffer_success(): \ndesc.sdp:\n"+desc.sdp+"desc:", desc); pc1.setLocalDescription(desc); // Establecer RTCPeerConnection generado por Offer SDP usando el método setLocalDescription. // Cuando el lado lejano envía su respuesta SDP, será necesario configurarlo usando el método setRemoteDescription // Hasta que se implemente el segundo lado, no hacemos nada // pc2_receivedOffer(desc); )

El segundo parámetro es una función de devolución de llamada que se llamará en caso de error.

Función pc1_createOffer_error(error)( console.log("pc1_createOffer_success_error(): error:", error); )

Y declaremos una función de devolución de llamada a la que se pasarán los candidatos de ICE a medida que se determinen:

Función pc1_onicecandidate(evento)( if (event.candidate) ( console.log("pc1_onicecandidate():\n"+ event.candidate.candidate.replace("\r\n", ""), event.candidate); // Hasta que se implemente el segundo lado, no hacemos nada // pc2.addIceCandidate(new RTCIceCandidate(event.candidate)); ) )

Y también una función de devolución de llamada para agregar un flujo de medios desde el lado lejano (para el futuro, ya que por ahora solo tenemos una RTCPeerConnection):

Función pc1_onaddstream(evento) ( console.log("pc_onaddstream()"); remotoVideo1.src = URL.createObjectURL(event.stream); )

Cuando hace clic en el botón "createOffer", crearemos una RTCPeerConnection, configuraremos los métodos onicecandidate y onaddstream y solicitaremos la formación de un SDP de oferta llamando al método createOffer():

Función createOffer_click() ( console.log("createOffer_click()"); pc1 = new webkitRTCPeerConnection(servers); // Crear RTCPeerConnection pc1.onicecandate = pc1_onicecandate; // Función de devolución de llamada para procesar candidatos ICE pc1.onaddstream = pc1_onaddstream; // Función de devolución de llamada llamada cuando aparece un flujo de medios desde el otro lado. Aún no hay ninguno pc1.addStream(localStream); // Transmitamos el flujo de medios local (suponiendo que ya se haya recibido) pc1.createOffer(// Y en realidad solicite la formación de la Oferta pc1_createOffer_success , pc1_createOffer_error, offerConstraints); )

Guardemos el archivo como rtctest2.html, lo carguemos en el servidor, lo abramos en un navegador y veamos en la consola qué datos se generan durante su funcionamiento. El segundo vídeo aún no aparecerá, ya que solo hay un participante. Recordemos que SDP es una descripción de los parámetros de una sesión de medios, los códecs disponibles, los flujos de medios y los candidatos ICE son posibles opciones para conectarse a un participante determinado.

Formación de Answer SDP e intercambio de candidatos del ICE

Tanto el SDP de Oferta como cada uno de los candidatos de ICE deben ser transferidos al otro lado y allí, luego de recibirlos, RTCPeerConnection llama a los métodos setRemoteDescription para el SDP de Oferta y addIceCandidate para cada candidato de ICE recibido del lado lejano; de manera similar en reverso para Answer SDP y candidatos remotos de ICE. La propia Respuesta SDP se forma de manera similar a la Oferta; la diferencia es que no se llama al método createOffer, sino al método createAnswer, y antes de eso, el método RTCPeerConnection setRemoteDescription se pasa al SDP de oferta recibido de la persona que llama.

Agreguemos otro elemento de video al HTML:

Y una variable global para la segunda RTCPeerConnection bajo la declaración de la primera:

Varpc2;

Procesamiento de oferta y respuesta SDP

La formación de Answer SDP es muy similar a Offer. En la función de devolución de llamada llamada tras la formación exitosa de una Respuesta, similar a la Oferta, daremos una descripción local y pasaremos la Respuesta SDP recibida al primer participante:

Función pc2_createAnswer_success(desc) ( pc2.setLocalDescription(desc); console.log("pc2_createAnswer_success()", desc.sdp); pc1.setRemoteDescription(desc); )

La función de devolución de llamada, llamada en caso de error al generar la Respuesta, es completamente similar a la Oferta:

Función pc2_createAnswer_error(error) ( console.log("pc2_createAnswer_error():", error); )

Parámetros para formar la respuesta SDP:

Var AnswerConstraints = ( "obligatorio": ( "OfferToReceiveAudio":true, "OfferToReceiveVideo":true));

Cuando el segundo participante reciba la Oferta, crearemos una RTCPeerConnection y formaremos una Respuesta de la misma manera que la Oferta:

Función pc2_receivedOffer(desc) ( console.log("pc2_receiveOffer()", desc); // Crea un objeto RTCPeerConnection para el segundo participante de la misma manera que el primero pc2 = new webkitRTCPeerConnection(servers); pc2.onicecandidate = pc2_onicecandidate ; // Establece el controlador de eventos cuando aparece el candidato ICE pc2.onaddstream = pc_onaddstream; // Cuando aparece una secuencia, conéctala a HTML pc2.addStream(localStream); // Transfiere la secuencia de medios local (en nuestro ejemplo, la segunda el participante tiene el mismo que el primero) // Ahora, cuando la segunda RTCPeerConnection esté lista, le pasaremos el SDP de oferta recibido (pasamos el flujo local al primero) pc2.setRemoteDescription(new RTCSessionDescription(desc)); // Solicita la segunda conexión para generar datos para el mensaje de respuesta pc2.createAnswer(pc2_createAnswer_success, pc2_createAnswer_error, answerConstraints); )

Para transferir la Oferta SDP del primer participante al segundo en nuestro ejemplo, descomentémoslo en la función pc1 crearoferta línea de llamada de éxito ():

Pc2_recibidaOferta(desc);

Para implementar el procesamiento de candidatos ICE, descomentemos en el controlador de eventos de preparación de candidatos ICE del primer participante pc1_onicecandidate() su transferencia al segundo:

Pc2.addIceCandidate(nuevo RTCIceCandidate(evento.candidato));

El controlador de eventos de preparación del candidato ICE del segundo participante es similar al primero:

Función pc2_onicecandidate(evento) ( if (event.candidate) ( console.log("pc2_onicecandidate():", event.candidate.candidate); pc1.addIceCandidate(new RTCIceCandidate(event.candidate)); ) )

Función de devolución de llamada para agregar una transmisión multimedia del primer participante:

Función pc2_onaddstream(evento) ( console.log("pc_onaddstream()"); remotoVideo2.src = URL.createObjectURL(event.stream); )

Terminando la conexión

Agreguemos otro botón al HTML.

Colgar

Y una función para terminar la conexión.

Función btnHangupClick() ( // Desconecta el video local de los elementos HTML, detiene la transmisión de medios local, set = null localVideo1.src = ""; localStream.stop(); localStream = null; // Para cada participante, deshabilita el video de HTML elementos, cierre la conexión, establezca el puntero = null remoteVideo1.src = ""; pc1.close(); pc1 = null; remoteVideo2.src = ""; pc2.close(); pc2 = null; )

Guardémoslo como rtctest3.html, subámoslo al servidor y abrimoslo en el navegador. Este ejemplo implementa la transmisión bidireccional de flujos de medios entre dos RTCPeerConnections dentro de la misma pestaña del navegador. Para organizar el intercambio de Oferta y Respuesta SDP, candidatos ICE entre los participantes y otra información a través de la red, en lugar de llamar directamente a los procedimientos, será necesario implementar el intercambio entre los participantes utilizando algún tipo de transporte, en nuestro caso - sockets web.

Transmisión de pantalla

La función getUserMedia también puede capturar la pantalla y transmitir como MediaStream especificando los siguientes parámetros:

Var mediaStreamConstraints = ( audio: falso, video: ( obligatorio: ( chromeMediaSource: "pantalla"), opcional: ) );

Para acceder con éxito a la pantalla se deben cumplir varias condiciones:

  • habilitar el indicador de captura de pantalla en getUserMedia() en chrome://flags/,chrome://flags/;
  • el archivo fuente debe descargarse mediante HTTPS (origen SSL);
  • no se debe solicitar la transmisión de audio;
  • No se deben ejecutar varias solicitudes en una pestaña del navegador.
Bibliotecas para WebRTC

Aunque WebRTC aún no está terminado, ya han aparecido varias bibliotecas basadas en él. JsSIP está diseñado para crear softphones basados ​​en navegador que funcionan con conmutadores SIP como Asterisk y Camalio. PeerJS facilitará la creación de redes P2P para el intercambio de datos y Holla reducirá la cantidad de desarrollo necesario para las comunicaciones P2P desde los navegadores.

Node.js y socket.io

Para organizar el intercambio de candidatos SDP e ICE entre dos RTCPeerConnections a través de la red, utilizamos Node.js con el módulo socket.io.

Se describe la instalación de la última versión estable de Node.js (para Debian/Ubuntu).

$ sudo apt-get install python-software-properties python g++ make $ sudo add-apt-repository ppa:chris-lea/node.js $ sudo apt-get update $ sudo apt-get install nodejs

Instalación para otros SO descrito

Vamos a revisar:

$ echo "sys=require("util"); sys.puts("Mensaje de prueba");" > nodetest1.js $ nodejs nodetest1.js

Usando npm (Node Package Manager) instalaremos socket.io y el módulo express adicional:

$ npm instala socket.io express

Probémoslo creando un archivo nodetest2.js para el lado del servidor:

$ nano nodetest2.js var aplicación = require("express")(), servidor = require("http").createServer(app), io = require("socket.io").listen(server); servidor.escuchar(80); // Si el puerto 80 está libre app.get("/", function (req, res) ( // Al acceder a la página raíz res.sendfile(__dirname + "/nodetest2.html"); // envía el archivo HTML) ) ; io.sockets.on("conexión", función (socket) ( // Al conectar socket.emit("evento del servidor", ( hola: "mundo" )); // envía un mensaje socket.on("evento del cliente" , función (datos) ( // y declarar un controlador de eventos cuando llega un mensaje del cliente console.log(datos); )); ));

Y nodetest2.html para el lado del cliente:

$ nano nodetest2.html var socket = io.connect("/"); // URL del servidor Websocket (la página raíz del servidor desde el que se cargó la página) socket.on("evento del servidor", función (datos) ( console.log(datos); socket.emit("evento del cliente", ( " nombre": "valor" )); ));

Iniciemos el servidor:

$ sudo nodejs nodetest2.js

y abra la página http://localhost:80 (si se ejecuta localmente en el puerto 80) en el navegador. Si todo es exitoso, en la consola JavaScript del navegador veremos el intercambio de eventos entre el navegador y el servidor al conectarnos.

Intercambio de información entre RTCPeerConnection a través de sockets web Parte del cliente

Guardemos nuestro ejemplo principal (rtcdemo3.html) con el nuevo nombre rtcdemo4.html. Incluyamos la biblioteca socket.io en el elemento:

Y al comienzo del script JavaScript, conectándose a websockets:

Var socket = io.connect("http://localhost");

Reemplacemos la llamada directa a las funciones de otro participante enviándole un mensaje a través de web sockets:

Función createOffer_success(desc) ( ... // pc2_receivedOffer(desc); socket.emit("oferta", desc); ... ) function pc2_createAnswer_success(desc) ( ... // pc1.setRemoteDescription(desc); socket .emit("respuesta", desc); ) función pc1_onicecandidate(evento) ( ... // pc2.addIceCandidate(new RTCIceCandidate(event.candidate)); socket.emit("ice1", evento.candidate); .. . ) función pc2_onicecandate(evento) ( ... // pc1.addIceCandidate(new RTCIceCandidate(event.candidate)); socket.emit("ice2", evento.candidate); ... )

En la función hangup(), en lugar de llamar directamente a las funciones del segundo participante, transmitiremos un mensaje a través de web sockets:

Función btnHangupClick() ( ... // remotoVideo2.src = ""; pc2.close(); pc2 = null; socket.emit("colgar", ()); )

Y agregue controladores de recepción de mensajes:

Socket.on("oferta", función (datos) ( console.log("socket.on("oferta"):", datos); pc2_receivedOffer(datos); )); socket.on("respuesta", función (datos) (е console.log("socket.on("respuesta"):", datos); pc1.setRemoteDescription(nueva RTCSessionDescription(datos)); )); socket.on("ice1", función (datos) ( console.log("socket.on("ice1"):", datos); pc2.addIceCandidate(new RTCIceCandidate(datos)); )); socket.on("ice2", función (datos) ( console.log("socket.on("ice2"):", datos); pc1.addIceCandidate(new RTCIceCandidate(datos)); )); socket.on("colgar", función (datos) ( console.log("socket.on("colgar"):", datos); remoteVideo2.src = ""; pc2.close(); pc2 = null; ) );

parte del servidor

En el lado del servidor, guarde el archivo nodetest2 con el nuevo nombre rtctest4.js y dentro de la función io.sockets.on("connection", function (socket) ( ... ) agregaremos la recepción y el envío de mensajes del cliente:

Socket.on("oferta", función (datos) ( // Cuando recibimos el mensaje "oferta", // dado que solo hay una conexión de cliente en este ejemplo, // enviaremos el mensaje de regreso a través del mismo socket .emit("oferta" , datos); // Si fuera necesario reenviar el mensaje a través de todas las conexiones, // excepto el remitente: // soket.broadcast.emit("oferta", datos); )); socket.on("respuesta", función (datos) ( socket.emit("respuesta", datos); )); socket.on("ice1", función (datos) ( socket.emit("ice1", datos); )); socket.on("ice2", función (datos) ( socket.emit("ice2", datos); )); socket.on("colgar", función (datos) ( socket.emit("colgar", datos); ));

Además, cambiemos el nombre del archivo HTML:

// res.sendfile(__dirname + "/nodetest2.html"); // Envía el archivo HTML res.sendfile(__dirname + "/rtctest4.html");

Iniciando el servidor:

$ sudo nodejs nodetest2.js

A pesar de que el código de ambos clientes se ejecuta dentro de la misma pestaña del navegador, toda la interacción entre los participantes en nuestro ejemplo se realiza completamente a través de la red y "separar" a los participantes no requiere ninguna dificultad especial. Sin embargo, lo que hicimos también fue muy simple: estas tecnologías son buenas porque son fáciles de usar. Aunque a veces sea engañoso. En particular, no olvidemos que sin los servidores STUN/TURN nuestro ejemplo no podrá funcionar en presencia de traducción de direcciones y firewalls.

Conclusión

El ejemplo resultante es muy convencional, pero si universalizamos ligeramente los controladores de eventos para que no difieran entre el llamante y el llamado, en lugar de dos objetos pc1 y pc2, creamos una matriz RTCPeerConnection e implementamos creación dinámica y eliminando elementos, obtendrás un video chat completamente utilizable. No hay detalles especiales asociados con WebRTC, y un ejemplo de un chat de video simple para varios participantes (así como los textos de todos los ejemplos en el artículo) se encuentra en el disco que viene con la revista. Sin embargo, ya se pueden encontrar bastantes en Internet. buenos ejemplos. En particular, se utilizó lo siguiente para preparar el artículo: simpl.info getUserMedia, simpl.info RTCPeerConnection, WebRTC Reference App.

Se puede suponer que muy pronto, gracias a WebRTC, se producirá una revolución no sólo en nuestra comprensión de las comunicaciones de voz y vídeo, sino también en la forma en que percibimos Internet en su conjunto. WebRTC se posiciona no solo como una tecnología para llamadas de navegador a navegador, sino también como una tecnología de comunicación en tiempo real. La comunicación por video que discutimos es solo una pequeña parte. opciones posibles su uso. Ya existen ejemplos de screencasting y colaboración, e incluso una red de entrega de contenido P2P basada en navegador que utiliza RTCDataChannel.




Arriba