martes, 5 de mayo de 2015

Web_RTC

WebRTC

Comenzamos con WebRTC. ¿Qué es webRTC y para que sirve?  WebRTC es una API(interfaz de programación de aplicaciones) que está siendo elaborada para permitir a las aplicaciones del navegador realizar llamadas de vozchat de vídeo y uso compartido de archivos P2P(Peer to Peer).

¿Por qué es tan importante webRTC? Los profesionales de las comunicaciones dicen que webRTC, va ser la tecnología del futuro principalmente porque es independiente de la plataforma(windows,linux,os...) Esto hace que cualquier usuario que use cualquier maquina sea capaz de comunicarse con otro.

En este tutorial, voy a intentar ser lo más claro posible para que la gente que este comenzando con estas tecnologías sean capaces de entenderlo. Recomiendo previamente que antes de leer mis explicaciones de como funciona webRTC, echen un vistazo al funcionamiento de simpleWebRTC, https://simplewebrtc.com/.

Bueno como en todos mis post publicados, voy a intentar ser lo más claro posible y vamos analizar el funcionamiento de webRTC en 4 PASOS sencillos.

PASO 0: Introducción a webRTC

PASO 1: Flujo de datos

PASO 2: Código javascript del cliente y del servidor de señalización.

PASO 3: Ejemplo de comunicación entre un Mac y un Windows.

*Nota: Todo el código de este tutorial y del anterior, lo podrás encontrar en:
https://github.com/graylinx/rtc

Comenzamos con el tutorial, en caso de que algo no sea entendido o este mal explicado publicarlo en el foro y lo debatiremos.

PASO 0: Introducción a webRTC

Lo primero y más importante que hay que entender en webRTC, es que necesitamos de un servidor de señalización para poder entablar una conversación. Una vez que ya obtengamos la información necesaria para poder hablar entre dos, el servidor de señalización se desvinculará y solo estaremos los Peer que queramos hablar. ¿Entonces es posible hablar mas de 2 Peer? Si es posible, pero nuestro tutorial es básico y se centra en la comunicación de 2 Peer.

¿Cómo funciona el establecimiento de la conexión? Pues utilizamos la API websocket que como ya explique en el post anterior, es una manera de establecer conexión bidireccional sin sobrecargas de gestión para obtener respuestas en tiempo real. Se basa en el protocolo TCP.
Durante la conexión y hasta el final del uso de la aplicación, utilizamos webRTC que permite a las aplicaciones del navegador realizar llamadas de voz, chat de video y uso compartido de archivos P2P sin plugins. WebRTC implenta tres APIs:
  1. MediaStream o GetUserMedia: Permite obtener streams de audio, video o combinaciones de ambos del dispositivo. Una vez obtenida la información de la cámara, la pantalla o el micrófono del usuario, podemos aplicarle efectos en el cliente, enviarla a nuestro servidor para almacenarla para cualquier tipo de aplicación social o podemos usar las siguientes APIs para enviar la información en tiempo real a otro usuario o incluso a varios usuarios.
  2. RTCPeerConnection: Esta API se encarga de realizar el streaming de video o audio, con todo lo que esto conlleva: procesar la señal, realizar la comunicación, ejecutar el code, administrar el ancho de banda, la seguridad, etc. Estas son tareas bastantes complejas y es API permite implementarlas, sin que el programador se tenga que preocupar por nada.
  3. RTCDataChannel: Dependiendo del tipo de aplicación que queramos, puede que necesitemos hacer streaming de otro tipo de datos que no sea video o audio. RTCDataChannel, realiza la comunicación bidireccional de cualquier tipo de datos entre pares, usando la misma API que websockets (la API utilizada para la comunicación bidireccional entre el cliente y el servidor). Permite que el flujo de datos sea fiable y la comunicación más lenta (TCP), o que no sea fiable y la comunicación sea más rápida (UDP).
Por último añadir como introducción de WeRTC, que tenemos versiones estables para Chrome escritorio, Chrome android, Firefox y Opera. Esta tecnología bajo mi punto de vista va ser clave para que JavaScript y HTML5 se conviertan en los lenguajes de desarrollo más usados para realizar aplicaciones móviles.

PASO 1: Esquema y análisis del flujo de datos

Comenzamos con lo realmente complicado de este tutorial. Vamos a intentar entender como funciona el siguiente diagrama de flujo de datos, ya que va ser clave para entender la práctica.

Vamos a ponernos ya en situación de un caso real: El PeerA va ser un ordenador Mac que quiere establecer una conexión con el PeerB que es un PC. Para ello se enfrentan a grandes dificultades como son los router NAT(IP Públicas/ IP Privadas), este es el verdadero problema de ipv4. Para solucionar el problema de las IP Privadas se inventaron los servidores STUN, para el caso de los routers Full Cone  y los servidores TURN para los routers Restricted Cone, Port Restricted Cone o Symmetric
Pero bueno poniéndonos en situación real, este problema nos influye si salimos de nuestra red, pero en nuestro caso vamos a simplificar la práctica y vamos a obviar los servidores STUN y TURN y nos vamos a centrar en WebRTC dentro de una LAN. Pos si alguien le interesa este tema, ya que le interesa probar webRTC desde red a otra, adjunto un link en el que se explica muy bien el problema que causa los NAT.
http://telefonia.blog.tartanga.net/2014/05/03/stun-turn-ice-upnp-alg-y-otros-el-lado-oscuro-de-la-telefonia-ip/

Continuamos entonces con el flujo de datos simplificado debido a que no vamos a salir de nuestra LAN. He intentado describir en una transparencia como se va a comportar webRTC a la hora de establecer conexión y en que consiste el server de señalización. Las lineas en rojo son mensajes que envía el server al cliente y las lineas azules mensajes que emitirá el cliente al server. Una vez que se complete todo este proceso podemos cerrar el servidor y comprobar si la conexión sigue existiendo entre los dos Peer.


En nuestro caso el Mac será el Peer iniciador, este concepto es muy importante en webRTC, ya que siempre tiene que haber un iniciador de la conexión que cree una habitación. El iniciador también será el encargado de realizar la llamada(offer) y el Peer2 que en nuestro caso es un PC será el que responda la contestación(answer) siempre y cuando entre en la misma habitación que hayan acordado previamente los dos Peers.

PASO 2: Código javascript del cliente y del servidor de señalización.

Una vez entendido la explicación de como se consiguen comunicar 2Peer que están en la misma red, vamos al código javascript que nos permite implentar lo que queremos hacer. Primero voy a empezar explicando el código del servidor de señalización que es muy simple comparado con el del cliente. Utilizamos la librería socket.io ya utilizada en la práctica anterior.

A grandes rasgos el servidor, cuyo fichero he llamado app.js, solo se tiene que encargar de recibir mensajes y reenviárselos a los peer.

Una vez que arrancamos el servidor con el comando node app.js en nuestra consola, lo primero que hace es inicializar estas variables y se queda escuchando en el puerto 8181esperando cualquier tipo de petición (req).
Consta de las siguientes variables:
app.js
Cuando un cliente decida hacer una petición Get: IP:PORT, el servidor enviará el archivo html con sus correspondiente script escrito en javascript donde estarán implementadas las APIs de webRTC. Entonces vamos a analizar que ficheros enviamos al cliente:
Lo primero del cliente es su documento html, al que he llamado index.html.
index.html
El html contiene tres fichero js que hacen referencia a la librería socket.io, a un fichero adapter.js que no vamos a profundizar en el y al fichero cliente.js que contiene todo el código necesario para hacer posible la comunicación webRTC.
Fichero cliente.js, si analizamos poco a poco de  lo que se compone este código, nada más arrancar el fichero procedente del servidor el cliente ejecuta el código cliente.js inicializando las siguientes variables:
cliente.js
Lo que hace el cliente es crear una habitación y enviar un mensaje al servidor, esta parte es la que se encarga las linea de la 53 a la 56 de la figura anterior.

Cuando al servidor le llega el mensaje del cliente ("create or join"), lo analiza y comprueba si es el primer o el segundo cliente, enviando diferentes mensajes dependiendo del cliente que haya llegado.
app.js
Ahora es cuando el cliente recibe un mensaje dependiendo de si es 1ºpeer o 2ºpeer. En caso de que sea 1ºPeer hace lo siguiente, haciendo uso del API getusermedia:
cliente.js
Si da el caso de que ya hay un peer en la habitación, al 2º cliente le llegaran un mensajes de tipo join, que el cliente recibirá y pondrá el canal listo para procesar las ofertas y enviar las respuestas, también haciendo uso del API getusermedia.
cliente.js

Una vez que todo este listo el cliente1 hará la llamada. No sin antes preparar la conexión a partir del API RTCPeerConexión. Donde el cliente iniciador enviará la oferta SDP al servidor y el servidor se la reenviará al cliente2, tal y como se mostraba en el esquema del PASO 1. Es entonces cuando el cliente2 hace el mismo procedimiento pero a la inversa (answer).

cliente.js
La recepción de estos mensajes en el servidor es algo muy simple, solamente se encarga de recibirlos y enviarlos.
app.js
Con esto podríamos entender por encima como se comporta el proceso de comunicación con el servidor de señalización, para poder entablar comunicación con otro Peer. Y ahora es cuando llega la esencia de esta tecnología. Una vez que dispongamos la información necesaria para poder comunicarnos con nuestro otro Peer, el servidor puede ser desvinculado, ya que no cumple ninguna función más que la mencionada. Esto nos permitirá no depender de servidores y no tener que ser escuchados por gente que no deseemos o simplemente por el hecho de hacer una web mucho más abierta y sin trabas.

¿Cómo no vamos a depender del servidor?  La prueba de que no dependemos para nada del servidor, esta por ejemplo en el chat que he implentado, utilizando el API RTCDataChannel. Para terminar la explicación del código cliente, voy a explicar como se comporta este APIs que tiene implementado webRTC, en el que consiste en una comunicación en tiempo real muy similar a la que ofrece websocket. La diferencia de websocket con datachanel esta en el protocolo de comunicaciones que utiliza "UDP" poco fiable, pero muy rápido. También se puede configurar para poder usar TCP en datachanel. Como vereís en la siguiente figura, simplemente tenemos que asignar el evento onclick al elemento "button" para que se active la función sendata, en la cual se inicializará la variable data con el valor del texto que le metamos en campo "sendTextarea". Por último como el peer1 sabe donde tiene que enviar la información, no necesita de ningún intermediario, es decir la comunicación es fluida entre el peer1 y el peer2.


cliente.js
PASO 3: Ejemplo de comunicación entre un Mac y un Windows en una misma red (LAN).

Para terminar el tutorial se me ha ocurrido mostrar un ejemplo de la interfaz gráfica de como hablan un Mac OS, con un PC. Para ello tenemos que editar primero la variable socket que se encuentra en el cliente.
cliente.js
y remplazarla por la ip pública que tenemos en nuestro router, que en mi caso es la:
terminal
cliente.js
Una vez inicializadas esta variable, lo único que tenemos que hacer es abrir la terminal y arrancar el server app.js
terminal
A continuación arrancaremos Mozilla en el Mac como peer iniciador, con la siguiente url: 192.168.1.13:8181 e introduciremos el nombre de la sala, en este caso sala1.
ORDENADOR MAC

Lo mismo debemos de hacer con el PC, pero ahora lo haremos desde un navegador chrome. Y esto es lo que nos aparece:


Como vemos, parece que el establecimiento de conexión esta ya terminado solo falta que el iniciador de a aceptar y que el PC escriba el mismo nombre de la sala y le de también a aceptar. Una vez que ambos estén dentro veremos los siguiente:
PC de R2D2
Mac de Darth Vader

Solo nos faltaría interrumpir el server y ver si es posible la comunicación (en la termina ctrl+c).


Este último paso os lo dejo a vosotros para que comprobéis que todo lo que os he explicado en este tutorial es cierto. Espero que os haya gustado y nos vemos en otra.

Un saludo. 

Mario.