Tips de Desarrollo Web

Escrito por Juan David Nicholls

NAVEGACIÓN

Aplicaciones en Tiempo Real, HTML5 y Node.JS

En este artículo voy a explicar sobre la API que ofrece Html5 para permitir la comunicación bidireccional entre el cliente y el servidor que son los WebSockets y también las dos soluciones en tiempo real que permite Node.JS, mediante WebSockets y Socket.IO.

WebSockets y Socket.IO

Para aclarar, Node.JS es un entorno de programación dirigido por eventos, es decir es el usuario el que define el flujo del programa mediante la interfaz de usuario, en este caso la página web y sigue un modelo non-blocking I/O, es decir un modelo no bloqueante de entrada y salida, esto nos permite hacer una programación asíncrona de entrada y salida, parecido al ajax en javascript y tiene un muy buen rendimiento debido a que corre todas las conexiones entrantes sobre un mismo hilo y le deja la labor al Sistema Operativo de realizar todas las operaciones en la pila de ejecución. Node.JS ha cogido mucho empuje en la comunidad web por ser completamente basado en Javascript, el cual hasta ahora se había empleado únicamente del lado del cliente (validaciones, animaciones y ajax).

Para entender más sobre Node.Js puedes entrar al siguiente link, ir al Sitio Oficial, entrar a la Comunidad o visualizar los módulos existentes aquí.

  • Ejemplo de WebSockets en HTML5

Para iniciar crearemos una página sencilla html la cual se conectará a un servidor de ejemplo suministrado por WebSockets, el cual recibirá los mensajes que nosotros le mandemos y como un eco los devolverá, al principio esto puede parecer que no tiene algo de utilidad, pero si la página estuviera en nuestro servidor, el servidor mostraría el mensaje a todo los clientes que estén visualizando esa página parecido a un chat.

La página pueden hacerla en cualquier editor de texto como Notepad, Notepad++, Gedit, Sublime Text, etc. Yo en todos los ejemplos he de emplear Visual Studio, porque me fascina completamente este IDE, veremos muchos tips de ASP.NET y además el editor de código permite, entre otras cosas, mantener organizado los niveles de sangría (identación) mediante Ctrl + K + D, y visualizar la sangría al presionar Ctrl + R + W, esto con el fin de organizarnos.

Creamos un página html

Crear una página html

Crearemos un div donde se mostraran los mensajes, un input donde se escribirán para posteriormente ser envidados y un botón para enviarlos, todo esto de una manera sencilla. Algo muy bonito a tener en cuenta es que cuando abres un tag "<", Visual Studio te muestra los posibles elementos html que has de utilizar y es solo buscar el elemento deseado y presionar 2 veces Tab, automáticamente lo generará.

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4.     <meta charset="utf-8" />
  5.     <title></title>
  6. </head>
  7. <body>
  8.     <input id="Message" type="text" name="name" value="" />
  9.     <button type="button" id="Send">Enviar</button><br />
  10.         <div id="Messages"></div>
  11. </body>
  12. </html>

Siguiendo el ejemplo dado en WebSockets, me he de conectar al servidor mediante javascript

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4.     <meta charset="utf-8" />
  5.     <title></title>
  6. </head>
  7. <body>
  8.     <input id="Message" type="text" name="name" value="" />
  9.     <button type="button" id="Send">Enviar</button><br />
  10.     <div id="Messages"></div>
  11.     <script>
  12.         var WebSocket = new WebSocket("ws://echo.websocket.org");
  13.         WebSocket.addEventListener("open", function () {
  14.             console.log("Conectado");
  15.         });
  16.     </script>
  17. </body>
  18. </html>

Como podemos observar, hemos creado un elemento "script" donde emplearemos el javascript necesario para conectarnos, creamos en una variable “WebSocket” una instancia de WebSockets con la Url del Servidor de ejemplo. Y posteriormente empleamos un evento addEventListener que ejecutará una función cuando la conexión se haya abierto con éxito. El console.log() nos permite observar en la consola del Browser como en Chrome o en la consola del FireBug en Firefox (dando click derecho – inspeccionar) la palabra "Conectado" si la conexión se ha abierto con éxito. De no ser así, ver en la Documentación de WebSockets el soporte para saber si tu navegador es compatible.

Consola del Navegador

También en la pestaña Network podemos visualizar si la Url de los WebSockets se ha cargado perfectamente mediante el "Status Code", el 101 significa que la conexión se ha establecido correctamente.

Conexión WebSocket

Y para finalizar este ejemplo, agregamos el evento "message" que ejecuta una función cuando el servidor nos manda un mensaje y tenemos un evento click del botón, el cual se encargará de mandar el mensaje al servidor. Más adelante haremos ejemplos con Node.JS, que permitirá que nuestro servidor muestre a todos los clientes el mensaje enviado y que tenga mayor compatibilidad, mediante Socket.IO, el cual utiliza diferentes técnicas incluyendo WebSockets para garantizar aplicaciones en tiempo real.

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4.     <meta charset="utf-8" />
  5.     <title></title>
  6. </head>
  7. <body>
  8.     <input id="Message" type="text" name="name" value="" />
  9.     <button type="button" id="Send">Enviar</button><br />
  10.     <div id="Messages"></div>
  11.     <script type="text/javascript">
  12.         var WebSocket = new WebSocket("ws://echo.websocket.org");
  13.         WebSocket.addEventListener("open", function () {
  14.             console.log("Conectado");
  15.         });
  16.         WebSocket.addEventListener("message", function (message) {
  17.             document.getElementById("Messages").innerHTML += message.data + "<br />";
  18.         });
  19.         document.getElementById("Send").addEventListener("click", function () {
  20.             socket.send(document.getElementById("Message").value);
  21.         });
  22.     </script>
  23. </body>
  24. </html>
  • Ejemplos de WebSockets y Socket.IO con Node.JS

Si no tienes instalado Node.JS, entra al siguiente link, automáticamente reconocerá tu Sistema Operativo y al darle click al botón "Install", procederá a bajarte la última versión disponible de Node.JS correspondiente a tu Sistema Operativo.

Node.js

La instalación es muy sencilla y automáticamente creará una variable del Sistema. Como Node.JS no tiene una interfaz gráfica de Usuario, debes abrir la consola, en Windows XP, ejecutar y escribir cmd, en Windows 7 inicio cmd y en windows 8, buscamos en Aplicaciones “Node.js command prompt”, o terminal si estas en linux.

Node.js command prompt

En la consola nos ubicamos en la carpeta donde realizaremos nuestra aplicación con Node.JS, en Windows con “cd nombre”, entramos a una carpeta con ese nombre, con “cd ..” salimos de esa carpeta y con “dir” visualizamos los archivos en donde estamos situados. Procedemos a instalar el módulo Socket.IO de la siguiente manera.

Instalando Socket.io

Al terminar de instalar el paquete, crearemos un archivo javasript server.js el cual será el encargado de montar nuestro servidor con Node.JS. Como ya había comentado anteriormente Node.JS es un lenguaje de programación totalmente javascript, por lo tanto todos nuestros archivos encargados de configurar el servidor serán archivos javascript (módulos).

Creando un Javascript

El cual se configurará de la siguiente manera

server.js
  1. var io = require('socket.io').listen(3000);
  2. io.sockets.on('connection', function (socket) {
  3.     socket.on('message', function (mensaje) {
  4.         io.sockets.send(mensaje);
  5.     });
  6. });

Donde:

  • io es una variable que va a instanciar el módulo socket.io y estará escuchando en el puerto 3000.
  • io.sockets son todos los clientes que se conectaran al servidor, y escuchará el evento connection que ejecutará una función cuando un cliente se conecte al servidor.
  • socket es un cliente, el cual tendrá un evento message que es un evento que se ejecuta cuando cuando el servidor recibe un mensaje del cliente, es aquí cuando devolvemos el mismo mensaje, donde tenemos 3 opciones básicas.
    1. io.sockets.send: este mandará el mensaje a todos los clientes.
    2. socket.broadcast.send: este mandará el mensaje a todos los clientes, excepto al que lo mandó.
    3. socket.send: este mandará el mensaje al cliente que lo mandó.

Ahora procedemos a modificar el html

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4.     <meta charset="utf-8" />
  5.     <title></title>
  6. </head>
  7. <body>
  8.     <input id="Message" type="text" name="name" value="" />
  9.     <button type="button" id="Send">Enviar</button><br />
  10.     <div id="Messages"></div>
  11.     <script src="http://localhost:3000/socket.io/socket.io.js"></script>
  12.     <script type="text/javascript">
  13.         socket = io.connect("http://localhost:3000");
  14.         socket.on("connect", function () {
  15.             console.log("Conectado");
  16.         });
  17.         socket.on("message", function (message) {
  18.             document.getElementById("Messages").innerHTML += message + "<br />";
  19.         });
  20.         document.getElementById("Send").addEventListener("click", function () {
  21.             socket.send(document.getElementById("Message").value);
  22.         });
  23.     </script>
  24. </body>
  25. </html>

Aquí cambian unas cuantas cosas, primero cargamos un javascript que viene con socket.io el cual nos permite ejecutar los eventos que nos ofrece el módulo y lo cargamos desde el puerto que destinamos. Después llamamos una variable socket que será nuestra conexión con el servidor en el puerto destinado y tendremos los mismos eventos que en el ejemplo anterior pero que se llaman de una forma un poco distinta, propia de socket.io “on”.

Posteriormente salvamos los cambios, y teniendo la consola en la carpeta de nuestra aplicación, la cual contiene nuestro server.js y nuestro Index.html, ejecutamos nuestro servidor con el comando “node”.

Iniciamos nuestro servidor Node.js

Si todo salió bien, al presionar enter no debe salir ningún mensaje de error, se debe de ver como el ejemplo anterior. Para confirmar que nuestro servidor esta OK, abrimos la pagina en un navegador como Chrome.

Socket.io funcionando

Hasta ahora hemos manejado Socket.io como lo hicimos con los WebSockets, más sin embargo Socket.io propone una forma mucho más escalable, mediante nuestros propios eventos.

Por lo tanto vamos a hacer un evento para cuando el servidor manda un mensaje al cliente llamado “mensaje_servidor” y otro evento para cuando el cliente le manda el mensaje al servidor “mensaje_cliente”.

server.js
  1. var io = require('socket.io').listen(3000);
  2. io.sockets.on('connection', function (socket) {
  3.     socket.on('mensaje_cliente', function (mensaje) {
  4.         io.sockets.emit("mensaje_servidor", mensaje);
  5.     });
  6. });

Index.html
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4.     <meta charset="utf-8" />
  5.     <title></title>
  6. </head>
  7. <body>
  8.     <input id="Message" type="text" name="name" value="" />
  9.     <button type="button" id="Send">Enviar</button><br />
  10.     <div id="Messages"></div>
  11.     <script src="http://localhost:3000/socket.io/socket.io.js"></script>
  12.     <script type="text/javascript">
  13.         socket = io.connect("http://localhost:3000");
  14.         socket.on("connect", function () {
  15.             console.log("Conectado");
  16.         });
  17.         socket.on("mensaje_servidor", function (message) {
  18.             document.getElementById("Messages").innerHTML += message + "<br />";
  19.         });
  20.         document.getElementById("Send").addEventListener("click", function () {
  21.             socket.emit("mensaje_cliente", document.getElementById("Message").value);
  22.         });
  23.     </script>
  24. </body>
  25. </html>

Aquí podemos identificar que ya no hacemos uso de la función “send”, sino de la función “emit”. Esta última se diferencia porque nos permite crear un evento con cualquier nombre que le queramos dar y el dato a enviar. Por lo tanto ya tenemos muchos más control de nuestra aplicación en tiempo real y hemos finalizado con éxito los ejercicios.

Espero que lo hayan disfrutado enormemente, al igual que lo fue para mi, hasta la próxima ;)

blog comments powered by Disqus