Lección 13: WebSockets
A diferencia de AJAX, el API de WebSocket es una tecnología avanzada que nos permite la comunicación bidireccional entre un cliente y un servidor. El servidor puede enviar mensajes al cliente y el cliente al servidor por el mismo camino.
Esta tecnología es indispensable para hacer tareas como:
- Aplicaciones en tiempo real, como un Chat o una red social.
- Envío de mensajes a un cliente específico, como unas notificaciones.
- Envío de mensajes masivos, como un videojuego multijugador.
- Aplicaciones de colaboración, como Google Drive o Notion.
Servidor
Para ilustrar las funcionalidades de WebSocket sin recurrir a servicios complejos o de pago, crearemos un pequeño servidor. Esta lección no aspira a enseñar backend con JavaScript o ahondar en Node
, sino ofrecer una elemental herramienta para aprender WebSockets.
Crearemos un servidor que devolverá cualquier información enviada a todos clientes conectados (Broadcast
).
Primero nos aseguramos que disponemos de Node.js
(binario para la ejecución de JavaScript) y npm
(gestor de paquetes JavaScript) instalado en el equipo.
node --version
npm --version
En ambos casos nos enseñará la versión instalada. En caso contraría mostrará un error que deberemos arreglar antes de continuar.
Ahora instalaremos las bibliotecas de WebSockets
.
Nos situamos sobre una carpeta nueva, para no mezclar con otros trabajos, y ejecutaremos.
npm install ws
Creamos un archivo llamado index.js
, donde nos encontramos situados, y pega el siguiente código.
// Importaciones
const WebSocket = require('ws');
const http = require('http');
// Creamos una instacia del servidor HTTP (Web)
const server = http.createServer();
// Creamos y levantamos un servidor de WebSockets a partir del servidor HTTP
const wss = new WebSocket.Server({ server });
// Escuchamos los eventos de conexión
wss.on('connection', function connection(ws) {
// Escuchamos los mensajes entrantes
ws.on('message', function incoming(data) {
// Iteramos todos los clientes que se encuentren conectados
wss.clients.forEach(function each(client) {
if (client.readyState === WebSocket.OPEN) {
// Enviamos la información recibida
client.send(data);
}
});
});
});
// Levantamos servidor HTTP
server.listen(8080);
console.log('Servidor funcionando. Utiliza ws://localhost:8080 para conectar.')
Guardamos.
Ahora levantaremos el servidor
node index.js
¡Listo! Para conectarnos con el cliente usaremos ws://localhost:8080
. Lo dejamos funcionando y pasamos a crear un cliente.
Cliente
Conectar
Nativamente disponemos de un API para realizar las interacciones.
const miWebSocket = new WebSocket(url [, protocolos]);
Al igual que existe una diferencia entre http
y https
, siendo el último seguro, en el protocolo de WebSockets también nos la encontraremos.
- ws: WebSockets.
- wss: WebSockets seguro.
const miWebSocket = new WebSocket('ws://miservidor.com');
Siendo más seguro.
const miWebSocket = new WebSocket('wss://miservidor.com');
Además dispondremos de un evento que será lanzado al conectar.
const miWebSocket = new WebSocket('wss://miservidor.com');
function open () {
// Abre conexión
console.log("WebSocket abierto.");
}
miWebSocket.addEventListener('open', open);
Mensajes
Escuchar
Si queremos recoger los mensajes enviados por el servidor, u otros clientes, debemos estar atentos al evento message
.
const miWebSocket = new WebSocket('wss://miservidor.com');
function message (evento) {
// Se recibe un mensaje
console.log("WebSocket ha recibido un mensaje");
// Mostrar mensaje en HTML
misRespuestas.innerHTML = misRespuestas.innerHTML.concat(evento.data, '<br>');
}
miWebSocket.addEventListener('message', message);
Emitir
Para enviar mensajes al servidor disponemos de la función send()
.
const miWebSocket = new WebSocket('wss://miservidor.com');
miWebSocket.send("Mi mensaje");
Gestión de errores
No siempre irá todo como esperamos, puede existir cortes de conexión por caídas de la red o problemas en el servidor.
Par ello estaremos alerta del evento error
.
const miWebSocket = new WebSocket('wss://miservidor.com');
function error (evento) {
// Ha ocurrido un error
console.error("WebSocket ha observado un error: ", evento);
}
miWebSocket.addEventListener('error', error);
Desconectar
Para la situación en que se desconecte el cliente o se rompa la conexión, posiblemente por un fallo importante, capturaremos el evento close
.
const miWebSocket = new WebSocket('wss://miservidor.com');
function close () {
// Cierra la conexión
console.log("WebSocket cerrado.");
}
miWebSocket.addEventListener('close', close);
Ejemplo
Con todo lo aprendido conectaremos con el servidor para enviar o recibir mensajes.
Crea un archivo llamado cliente-ws.html
con el siguiente contenido.
<!doctype html>
<html lang="es">
<head>
<meta charset="UTF-8"/>
<title>Ejemplo cliente de WebSocket</title>
</head>
<body>
<!-- Nuevo Mensaje -->
<input type="text" id="nuevo-mensaje">
<!-- Mensajes recibidos -->
<div id="respuestas"></div>
<script>
// Variables
const miWebSocket = new WebSocket('ws://localhost:8080');
const miNuevoMensaje = document.querySelector('#nuevo-mensaje');
const misRespuestas = document.querySelector('#respuestas');
// Funciones
function open () {
// Abre conexión
console.log("WebSocket abierto.");
}
async function message (evento) {
// Se recibe un mensaje
console.log("WebSocket ha recibido un mensaje");
// Mostrar mensaje en HTML
const mensajeRecibido = await evento.data.text(); // Arreglo para Node ya que devuelve Blob. Solo con 'evento.data' debería ser suficiente
misRespuestas.innerHTML = misRespuestas.innerHTML.concat(mensajeRecibido, '<br>');
}
function error (evento) {
// Ha ocurrido un error
console.error("WebSocket ha observado un error: ", evento);
}
function close () {
// Cierra la conexión
console.log("WebSocket cerrado.");
}
function enviarNuevoMensaje (evento) {
// Evento tecla Enter
if(evento.code === 'Enter') {
// Envia mensaje por WebSockets
miWebSocket.send(miNuevoMensaje.value);
// Borra texto en el input
miNuevoMensaje.value = '';
}
}
// Eventos de WebSocket
miWebSocket.addEventListener('open', open);
miWebSocket.addEventListener('message', message);
miWebSocket.addEventListener('error', error);
miWebSocket.addEventListener('close', close);
// Evento para envia nuevo mensaje
miNuevoMensaje.addEventListener('keypress', enviarNuevoMensaje);
</script>
</body>
</html>
Abre el archivo con diferentes ventanas al mismo tiempo para ver su funcionamiento.
Esta obra está bajo una Licencia Creative Commons Atribución-NoComercial-SinDerivadas 4.0 Internacional.
¿Me ayudas?
No te sientas obligado a realizarme una donación, pero cada aportación me ayuda a mantener el sitio en activo para que continúe existiendo y me motiva a continuar creando nuevo contenido.

- 1 café: Se mantiene el dominio durante 4 meses.
- 2 cafés: Se liquida 1 mes del Servidor Web.
- 3 cafés: Se paga 1 mes de Newsletter.
Comentarios
Nuevo comentario
Nueva replica {{ formatEllipsisAuthor(replyComment.author) }}
Escribe el primer comentario
{{ comments.length }} comentarios