History: Chat con socket.io

Revision made 7 years ago by Francisco Presencia. Go to the last revision.

En esta lección aprenderéis cómo hacer un chat en tiempo real con Node.js, y socket.io. Aprenderemos qué es eso de websockets y para qué es útil.

Websockets es una tecnología de comunicación en tiempo real bidireccional entre los navegadores y servidores. Es útil por ejemplo para hacer server-push en ciertos eventos, algo que hasta ahora sólo se podía hacer con short/long polling.

socket.io es una herramienta alojada en la web homónima cuyo objetivo es facilitar el uso de websockets y que proporciona funcionalidades más avanzadas como namespaces. Esto es muy útil para hacer chats más complejos ya que permite por ejemplo hacer una habitación en cada namespace.

Instalación

Primero que nada seguir la guia de instalación de Introducción y Preparación. Después, una vez estemos en nuestra carpeta del proyecto y hayamos hecho npm init, instalaremos la librería propia server, que nos servirá para crear nuestro back-end:

npm install server --save

Back-end

El back-end va a tener dos funcionalidades. Va a ser el encargado de cargar y mostrar los archivos necesarios (como un servidor estático) y va a actuar como capa de publicación de mensajes. Esto último quiere decir que va a recibir un mensaje de cierto tipo desde un usuario y se lo comunica al resto de usuarios conectados al back-end.

Vamos a usar las funciones que provee server, que ya incluye la librería socket.io. Como el back-end va a ser sencillo vamos a hacerlo en sólo 2 archivos de código. Primero creamos nuestro punto de entrada, index.js:

// index.js
const server = require('server');
const { get, socket } = server.router;
const { file } = server.reply;
const chat = require('./chat');

// Lanzar el servidor en el puerto 3000
server([

  // Mostrar el archivo principal a todo el mundo
  get('/', file('./public/index.html')),

  // Rutas para el chat
  socket('login',      chat.login),
  socket('message',    chat.message),
  socket('logout',     chat.logout),  // Manual
  socket('disconnect', chat.logout),  // Accidental/cerrar ventana

  // En caso que haya alguna petición sin responder
  get('*', ctx => 404)
]);

Y después creamos la lógica del chat.js:

// Guardar el nombre del usuario en el back-end y comunicarlo a todos
exports.login = ctx => {
  ctx.socket.user = ctx.data;
  console.log('Login:', ctx.socket.user);
  return ctx.io.emit('login', {
    user: ctx.socket.user,
    time: new Date()
  });
};

// Cuando alguien envía un mensaje, reenviarlo a todo el mundo
exports.message = ctx => {
  console.log('Message:', ctx.data);
  ctx.io.emit('message', {
    user: ctx.socket.user,
    text: ctx.data,
    time: new Date()
  });
};

// Cuando alguien hace logout mostrarselo también a todo el mundo
exports.logout = ctx => {
  console.log('Logout:', ctx.socket.user);
  if (!ctx.socket.user) return; // Para los que entran y salen sin hacer login
  return ctx.io.emit('logout', {
    user: ctx.socket.user,
    time: new Date()
  });
};

 

VARIOS PASOS INTERMEDIOS AQUÍ

Subir a Heroku

Esta sección se expandirá (todavía no) en otra lección.

Para subir sólo lo que nos interesa creamos .gitignore en el root de nuestro proyecto:

# Logs
logs
*.log
npm-debug.log*

# Dependency directories
node_modules

# dotenv environment variables file
.env

Por último iniciamos Git, Heroku y subimos la web:

git init

# Añadir nuestros archivos a Git
git add .gitignore
git commit -m "Ignoring some files"
git add .
git commit -m "Added full project"

# Crear la app de Heroku y añadir el remote
heroku create

# Subir la web a Heroku
git push heroku

¡Ya está! Ahora podemos abrir la URL que nos ha mostrado Heroku y ver nuestro chat en tiempo real.