Este artículo trata de describir como implementamos en nuestro Proyecto de Fin de Master WePlay un sistema en tiempo real de comentarios. La funcionalidad básicamente era que si estabas dentro de la página de un partido podías ver como los usuarios escribían comentarios en tiempo real sin necesidad de recargar la página como si de un chat se tratara. Para implementar esta funcionalidad empleamos Pusher, un servicio que más tarde describiré el cual utiliza tecnologías websockets.
Websocket es una tecnología que proporciona a nuestras aplicaciones web un canal de comunicación bidireccional sobre sockets TCP. Esta tecnología está diseñada para ejecutarse sobre navegadores y servidores web. La API de Websockets se encuentra actualmente en proceso de normalización por el W3C en la nueva versión de HTML5 sin embargo ya existen servicios que implementan esta tecnología que nos permite añadir funcionalidad en tiempo real a nuestras aplicaciones web.
Para implementar la funcionalidad empleamos un servicio en la nube que nos proporciona una capa de abstracción sobre el protocolo de websockets además herramientas de testeo y monitorización de lo que ocurre por sus sevidores. Este servicio se llama Pusher y permite crear aplicaciones en tiempo real como pueden ser chats, heramientas colaborativas, monitorización de datos en tiempo real, paneles, notificaciones push. En apenas minutos se puede configurar de una forma bastante sencilla el envío de información a nuestras aplicaciones evitando técnicas de long polling en ajax. Ahora es el servidor el que puede iniciar envío de informacion al cliente.
Pusher implementa una capa de eventos abstracta que puede ser escuchados en cliente y tambien emitidos desde cualquier servidor a través de su API. Este servicio nos da la posibilidad de generar y escuchar eventos con cualquier lenguaje y plataforma. Para implementar los servicios de Pusher disponemos de distintas librerías para clientes JavaScript, Java, Android, iOs, .Net, Ruby o ActionScript. Así como librerías a nivel servidor para Ruby, Node.js, Java, Phyton, PHP, .NET, Perl o Clojure.
Para el ejemplo hemos empleado una versión gratuita de Pusher para demostrar lo que nos permite hacer. Esta version free nos permite tener un máximo de 20 conexiones simultaneas y manejar 100.000 mensaje al día, lo cual nos puede permite probar como implementar nuestros servicios en tiempo real sin pensar inicialmente en la infraestructura ni las necesidades de la plataforma. Sin embargo pusher incluye distintos planes de precios que se pueden adaptar a la escalabilidad y necesidades de tu aplicación
De esta manera, en nuestra parte servidor cada vez que se generara con éxito un comentario en la aplicación, nuestro servidor web manda a pusher un mensaje que este reenviara a aquel que esté escuchando dicho evento. En nuestro lado servidor teníamos montado un Symfony 2 en el cual empleamos un Bundle de Terceros que nos integraba la librería de pusher PHP. Este bundle es LopiPusherBundle (https://github.com/laupiFrpar/LopiPusherBundle) y dentro de su github podemos ver como instalar y configurar fácilmente en nuestra aplicación web.
1 2 3 4 5 6 7 8 9 10 11 12 |
$comment= new Comment(); $comment->setComment($commentText); $comment->setGame($game); $comment->setUser($user); $dm->persist($comment); $dm->flush(); $pusher = $this->get('lopi_pusher.pusher'); serializer = $this->get('jms_serializer'); pusher->trigger('comments-channel', 'comments-'.$idGame, $serializer->serialize($comment, 'json')); |
Como vemos tras obtener el servicio que encapsula pusher, enviamos a través del canal comments-channel (el nombre definidos por nosotros) un json con los datos del comentario creado, y lo mandamos con el id de comments concatenado al id del partido de esta manera se identifica quien debe recibir dicho mensaje, solo los que se encuentren en ese partido. De esta manera recogerlo en la parte cliente es bastante sencillo. Veamos como podemos escuchar este evento en javascript.
1 2 3 4 5 6 7 8 |
var pusher = new Pusher(‘apikey’); var channel = pusher.subscribe('comments-channel'); channel.bind('comments-{{game.id}}', function(data) { obj = JSON.parse(data); // realizar acciones }); |
De esta manera podemos recibir vía javascript el evento recibido y manejar los datos recibidos con la acción que deseemos. En nuestra aplicación como enviamos la información del comentario la accion es generar la estructura html para representar estos datos en el frontend.
¿Que ventaja tiene emplear este tipo de tecnologías? La gran ventaja es que nos proporciona es funcionalidad en tiempo real sin necesidad de emplear polling el cual puede sobrecargar de peticiones al servidor y dándole la responsabilidad al servidor de comunicar la información necesaria en el lado cliente. Para profundizar más y ver las posibilidades que tiene este servidor os dejo el enlace a la documentación oficial de Pusher (https://pusher.com/docs)