Uso de Node.js y Websockets para construir un servicio de chat

Node.js y Websockets son la combinación perfecta para escribir aplicaciones muy rápidas y sin retrasos que pueden enviar datos a una gran cantidad de clientes. Entonces, ¿por qué no empezamos a aprender sobre estos dos temas construyendo un servicio de chat? Veremos cómo instalar los paquetes Node.js, servir una página estática al cliente con un servidor web básico y configurar Socket.io para comunicarse con el cliente.


Por qué elegir Node.js y Socket.io?


Entonces, ¿por qué usar este combo?

Hay muchas plataformas que pueden ejecutar una aplicación de chat, pero al elegir Node.js no tenemos que aprender un idioma completamente diferente, es solo JavaScript, pero del lado del servidor..

Node.js es una plataforma basada en el tiempo de ejecución de JavaScript de Chrome para facilitar la creación de aplicaciones en JavaScript que se ejecutan en el servidor. Node.js utiliza un modelo de E / S sin bloqueo, controlado por eventos, que lo hace perfecto para crear aplicaciones en tiempo real.

Cada vez se escriben más aplicaciones de Node.js teniendo en cuenta la comunicación en tiempo real. Un ejemplo famoso es BrowserQuest de Mozilla, un MMORPG escrito en su totalidad en Node.js cuyo código fuente ha sido publicado en Github.

Node.js viene con un gestor de paquetes incorporado: npm. Lo utilizaremos para instalar paquetes que ayudarán a acelerar nuestro proceso de desarrollo de aplicaciones..

Usaremos tres paquetes para este tutorial: Jade, Express y Socket.io.

Socket.io: el complemento Node.js Websockets

La principal característica de nuestra aplicación es la comunicación en tiempo real entre el cliente y el servidor..

HTML5 presenta Websockets, pero está lejos de ser compatible con todos los usuarios, por lo que necesitamos una solución de respaldo.

Socket.io es nuestra solución de respaldo: probará la compatibilidad de Websocket y, si no es compatible, utilizará Adobe Flash, AJAX o un iFrame..

Finalmente, soporta un conjunto muy grande de navegadores:

  • Internet Explorer 5.5+
  • Safari 3+
  • Google Chrome 4+
  • Firefox 3+
  • Ópera 10.61+
  • iPhone Safari
  • iPad Safari
  • Android WebKit
  • WebOs WebKit

También ofrece funciones muy fáciles para comunicarse entre el servidor y el cliente, en ambos lados.

Empecemos instalando los tres paquetes que necesitaremos..


Instalando nuestras dependencias

Npm nos permite instalar paquetes muy rápido, usando una línea, así que primero vaya a su directorio y pida a npm que descargue los paquetes necesarios:

npm instalar express jade socket.io

Ahora podemos comenzar a construir nuestro controlador del lado del servidor para servir a la página principal.

Vamos a guardar todo el código del lado del servidor en un "server.js" archivo que será ejecutado por Node.js.


Al servicio de una sola página estática


Para servir a nuestra página estática, utilizaremos Express, un paquete que simplifica todo el proceso de envío de la página del servidor..

Entonces, incluyamos este paquete en nuestro proyecto e iniciemos el servidor:

 var express = require ('express'), app = express.createServer ();

A continuación, debemos configurar Express para servir a la página desde las vistas del repertorio con el motor de plantillas de Jade que instalamos anteriormente..

Express usa un archivo de diseño de forma predeterminada, pero no lo necesitamos porque solo serviremos una página, por lo tanto, lo deshabilitaremos.

Express también puede servir un repertorio estático para el cliente como un servidor web clásico, por lo que le enviaremos un "público" Carpeta que contendrá todos nuestros archivos JavaScript, CSS y de imagen..

 app.set ('views', __dirname + '/ views'); app.set ('motor de vista', 'jade'); app.set ("opciones de visualización", diseño: falso); app.configure (function () app.use (express.static (__ dirname + '/ public')););

A continuación, vamos a crear dos carpetas dentro de nuestra carpeta de proyecto llamada "público" y "puntos de vista".

Ahora solo necesitamos configurar Express para servir un "home.jade" archivo, que crearemos en un momento, y luego configuraremos Express para que escuche un puerto específico.

Usaré el puerto 3000 pero puedes usar lo que prefieras.

 app.get ('/', function (req, res) res.render ('home.jade');); app.listen (3000);

Creación de la página de plantillas de Jade


Node.js usa motores de plantillas para servir páginas web. Es útil enviar páginas dinámicas y construirlas más rápido..

En este tutorial, utilizaremos Jade. Su sintaxis es muy clara y soporta todo lo que necesitamos..

"Jade es un motor de plantillas de alto rendimiento muy influenciado por Haml e implementado con JavaScript para Node".

Ahora, no voy a revisar Jade en detalle, si necesitas más ayuda, puedes encontrar documentación muy bien escrita en su repo de Github..

Configuración de Jade

Instalamos Jade anteriormente, pero debemos incluirlo en nuestro server.js archivo como hicimos para Express.

Por convención, incluimos nuestras bibliotecas en la parte superior de nuestro archivo para usarlas más adelante, sin tener que verificar si ya están incluidas. Así que coloca el siguiente código en la parte superior de tu "server.js" expediente :

 var jade = require ('jade');

Y eso completa nuestra configuración de Jade. Express ya está configurado para usar Jade con nuestros archivos de vista, para enviar una respuesta HTML, solo necesitamos crear ese archivo.

Creando nuestra página de inicio

Si iniciamos nuestro servidor ahora se bloqueará porque estamos solicitando a nuestra aplicación que envíe una página que aún no existe.

No vamos a crear una página con todas las funciones, solo algo básico que tiene un título, un contenedor para los mensajes, un área de texto, un botón de envío y un contador de usuarios..

Sigue adelante y crea un "home.jade" página dentro de la "puntos de vista" Carpeta con el siguiente código:

 doctype 5 html head title Script de chat (src = 'https: //ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js') script (src = "/ socket.io/socket. io.js ") script (src =" script.js ") body div.container header h1 Una aplicación de chat con Node.js y Socket.io input (type = 'text') # pseudoInput button # pseudoSet Establecer Pseudo div # chatEntries div # chatControls input (type = 'text') # messageInput button # submit Enviar

"Jade es todo acerca de la sangría"

El lenguaje jade tiene que ver con la sangría. Como puede ver, no necesitamos cerrar nuestros contenedores, solo basta con sangrar a los hijos del contenedor principal.

También usamos un punto "." y un signo de libra "#" para indicar la clase o el ID del elemento, como en un archivo CSS.

También enlazamos en tres scripts en la parte superior del archivo. El primero es jQuery de Google CDN, luego tenemos el script Socket.io que se entrega automáticamente por el paquete, y finalmente un "script.js" archivo que mantendrá todas nuestras funciones JS personalizadas.


La configuración del lado del servidor Socket.io


Socket.io está basado en eventos, al igual que Node. Su objetivo es hacer que las aplicaciones en tiempo real sean posibles en todos los navegadores y dispositivos móviles, difuminando las líneas entre estos diferentes mecanismos de transporte. Es libre de preocupaciones, en tiempo real y 100% JavaScript..

Al igual que los otros módulos, necesitamos incluirlo en nuestro server.js expediente. También encadenaremos nuestro servidor Express para escuchar las conexiones desde la misma dirección y puerto.

 var io = require ('socket.io'). listen (aplicación);

El primer evento que usaremos es el evento de conexión. Se dispara cuando un cliente intenta conectarse al servidor; Socket.io crea un nuevo socket que usaremos para recibir o enviar mensajes al cliente.

Comencemos por inicializar la conexión:

 io.sockets.on ('conexión', función (socket) // nuestros otros eventos ...);

Esta función toma dos argumentos, el primero es el evento y el segundo es la función de devolución de llamada, con el objeto socket.

Usando un código como este, podemos crear nuevos eventos en el cliente y en el servidor con Socket.io. Vamos a establecer la "seudo" evento y el "mensaje" evento siguiente.

Para hacer esto, es realmente simple, solo usamos la misma sintaxis, pero esta vez con nuestra enchufe objeto y no con el "io.sockets" (con una "s") objeto. Esto nos permite comunicarnos específicamente con un cliente..

Así que dentro de nuestra función de conexión, vamos a agregar en el "seudo" código de evento.

 socket.on ('setPseudo', function (data) socket.set ('pseudo', data););

La función de devolución de llamada toma un argumento, estos son los datos del cliente y en nuestro caso contiene el seudo. Con el "conjunto" Función, asignamos una variable al socket. El primer argumento es el nombre de esta variable y el segundo es el valor.

A continuación, necesitamos agregar el código para el "mensaje" evento. Obtendrá el pseudo usuario, transmitirá una matriz a todos los clientes que contenga el mensaje que recibimos, así como el pseudo usuario y lo registrará en nuestra consola..

 socket.on ('mensaje', función (mensaje) socket.get ('pseudo', función (error, nombre) var data = 'mensaje': mensaje, pseudo: nombre; socket.broadcast.emit (' mensaje ', datos); console.log ("usuario" + nombre + "enviar esto:" + mensaje);));

Esto completa nuestra configuración del lado del servidor. Si lo desea, puede seguir adelante y usar otros eventos para agregar nuevas funciones al chat..

Lo bueno de Socket.io es que no tenemos que preocuparnos por manejar las desconexiones de los clientes. Cuando se desconecta, Socket.io ya no recibirá respuestas a los mensajes de "latido" y desactivará la sesión asociada con el cliente. Si fue solo una desconexión temporal, el cliente se volverá a conectar y continuará con la sesión.


La configuración del lado del cliente de Socket.io

Ahora que nuestro servidor está configurado para administrar mensajes, necesitamos un cliente para enviarlos.

El lado del cliente de Socket.io es casi el mismo que el del servidor. También funciona con eventos personalizados y crearemos los mismos que en el servidor..

Así que primero, crea un "script.js" archivo dentro de la público carpeta. Almacenaremos todas nuestras funciones dentro de ella..

Primero necesitamos iniciar la conexión socket.io entre el cliente y el servidor. Se almacenará en una variable, que utilizaremos más adelante para enviar o recibir datos. Cuando la conexión no pasa ningún argumento, se conectará automáticamente al servidor que servirá a la página..

 var socket = io.connect ();

A continuación, vamos a crear algunas funciones de ayuda que necesitaremos más adelante. La primera es una función simple para agregar un mensaje a la pantalla con el pseudo usuario..

 función addMessage (msg, pseudo) $ ("# chatEntries"). append ('

'+ pseudo +': '+ msg +'

');

Este ayudante usa la función de agregar de jQuery para agregar un div al final de #chatEntries div.

Ahora vamos a escribir una función que podemos llamar cuando queremos enviar un nuevo mensaje..

 función sentMessage () if ($ ('# messageInput'). val ()! = "") socket.emit ('message', $ ('# messageInput'). val ()); addMessage ($ ('# messageInput'). val (), "Me", new Date (). toISOString (), true); $ ('# messageInput'). val (");

Primero, verificamos que nuestro área de texto no esté vacía, luego enviamos un paquete llamado "mensaje" al servidor que contiene el mensaje de texto, lo imprimimos en la pantalla con nuestro "agregar mensaje" Función, y finalmente eliminamos todo el texto del área de texto..

Ahora, cuando el cliente abre la página, primero debemos configurar el pseudo usuario. Esta función enviará el pseudo al servidor y mostrará el área de texto y el botón de envío..

 función setPseudo () if ($ ("# pseudoInput"). val ()! = "") socket.emit ('setPseudo', $ ("# pseudoInput"). val ()); $ ('# chatControls'). show (); $ ('# pseudoInput'). hide (); $ ('# pseudoSet'). hide (); 

Además, ocultamos los controles de configuración pseudo cuando se envían al servidor.

Ahora, como lo hicimos en el lado del servidor, necesitamos asegurarnos de que podemos recibir los mensajes entrantes y esta vez los imprimiremos en la pantalla. Usaremos la misma sintaxis, pero esta vez llamamos a la "agregar mensaje" función.

 socket.on ('mensaje', función (datos) addMessage (datos ['mensaje'], datos ['pseudo']););

Al igual que con nuestra configuración de servidor, el paquete que se envía al cliente es una matriz que contiene el mensaje y el pseudo. Así que llamamos a nuestro "agregar mensaje" Función que pasa en el mensaje y el pseudo, que extraemos del paquete de datos recibido..

Ahora solo necesitamos agregar la función de inicialización que se activa una vez que la página está completamente cargada.

 $ (function () $ ("# chatControls"). hide (); $ ("# pseudoSet"). click (function () setPseudo ()); $ ("# submit"). click (función ) Mensaje enviado();); );

Primero, escondemos los controles de chat antes de configurar el pseudo y luego configuramos dos escuchas de clics que escuchan los clics en nuestros dos botones de envío. El primero es para el pseudo y el segundo para los mensajes..

Y eso envuelve nuestro script del lado del cliente.


Conclusión

Ahora tenemos un servicio de chat de trabajo. Para iniciarlo, simplemente ejecuta el siguiente comando:

 nodo server.js

En su terminal, debería recibir un mensaje de Socket.io que dice que el servidor está iniciado. Para ver tu página ve a 127.0.0.1:3000 (o cualquier puerto que haya elegido previamente).


El diseño es muy básico, pero puedes agregar fácilmente una hoja de estilo con las transiciones CSS3 para los mensajes entrantes, los sonidos HTML5 o Bootstrap de Twitter..

Como puede ver, los scripts del servidor y del cliente son bastante similares: este es el poder de Node.js. Puedes construir una aplicación sin tener que escribir el código dos veces.

Finalmente, puede haber notado que solo tomó 25 líneas de código dentro de nuestro server.js Archivo para crear una aplicación de chat funcional, con un rendimiento increíble. Es muy corto, pero también funciona muy bien..

Ahora, si está interesado, he creado una mejor aplicación de servicio de chat, con un diseño atractivo, junto con algunas características adicionales. Está alojado en Nodester y el código fuente está en Github.

Aquí hay una vista previa de ello..


Gracias por leer.