Podría definirse como un tipo de 'puerto' en el cual se establece una comunicación abierta donde los datos fluyen bidireccionalmente entre cliente y servidor.
Los sockets no necesitan que se envíe una petición para poder responder. Ellos permiten un flujo de datos bidireccional por lo tanto solo es necesario escuchar el servidor y éste enviará un mensaje cuando esté disponible.
Para implementar la aplicación vamos a utilizar una librería Javascript basada en eventos llamada socket.io.
Ahora sí, empecemos a construir nuestra aplicación de mensajería en node.js con el objetivo de poner en práctica lo definido anteriormente.
Lo primero que debemos realizar es la creación de nuestro proyecto node, para esto corremos el siguiente comando.
Se instalan las dependencias.
Creamos un nuevo archivo llamado server.js
Ahora copiamos el siguiente código, para configurar nuestro servidor:
const http = require('http');
const express = require('express');
const socketIo = require('socket.io');
const app = express();
// Set up server
const server = http.createServer(app);
const io = socketIo(server);
io.on('connection', socket => {
console.log('User connected!');
socket.on('join', user => {
socket.user = { ...user, id: socket.client.id };
const activeUsers = socket.client.conn.server.clientsCount;
socket.emit('login', { activeUsers, user: socket.user });
socket.broadcast.emit('new user', { activeUsers, user: socket.user });
});
socket.on('message', msg => {
socket.broadcast.emit('message', msg);
});
socket.on('disconnect', () => {
console.log('User disconnected!');
socket.broadcast.emit('left', {
activeUsers: socket.client.conn.server.clientsCount,
user: socket.user
});
});
});
const port = process.env.PORT || 9000;
server.listen(port, () => console.log(`App running on port ${port}`));
Se definieron tres eventos:
La estructura de nuestro proyecto queda de la siguiente manera:
Ahora ejecutamos el servidor. Deberíamos ver el siguiente mensaje de salida:
Nota: Eventos importantes de socket.io.
// En escucha de evento
socket.on('escuchando', ...data)
// Enviar al emisor
socket.emit('enviar a emisor', ...data)
// Enviar a todos los clientes excepto al emisor
socket.broadcast.emit('enviar a todos excepto emisor', ...data)
// Enviar a todos los clientes conectados
io.emit('enviar a todos', ...data)
Socket.io nos brinda una librería que funciona tanto en cliente como servidor precisamente para conseguir la conexión bidireccional. En este caso se desarrolló un cliente utilizando React. Como el objetivo de la lección no es aprender react, entonces vamos a ejecutar los siguientes comandos para clonar el repositorio que contiene el código:
git clone git@github.com:crperz/chat-app.git
cd chat-app/front
Ahora ejecutemos el código en localhost:
npm install
npm start
Deberíamos de ver el siguiente mensaje de salida:
Esto significa que la aplicación ahora se está ejecutando. Para probar su funcionamiento se pueden abrir dos pestañas del navegador y chatear consigo mismo en localhost, pero esto no es muy interesante, porque la idea es poder chatear con más personas fuera de la máquina local.
Para resolver este problema, vamos a empaquetar la aplicación en un contenedor de docker y luego se propone su ejecución en AWS.
El primer paso para empaquetar la aplicación en un contenedor Docker es agregar un Dockerfile al proyecto. Este archivo es una serie de instrucciones que le indican a Docker cómo ensamblar una imagen (instalación de dependencias, pasos de compilación y ejecución de la aplicación). Veamos el Dockerfile.
# Descarga de la imagen base
FROM node:12.14.1-alpine
# Crear el directorio
WORKDIR /usr/src/app
# [<ubicación de="" los="" archivos="" a="" copiar="">, ]
COPY package*.json ./
# Instalación de dependencias
RUN npm install
# Copiar los demás archivos de la node app (docker cachea lo que ya tiene por lo tanto mejora el rendimiento al hacer las builds)
COPY . .
# El puerto por el cual va a exponer el contenedor, es el mismo puerto por donde está escuchando node
EXPOSE 9000
# Run app
CMD ["node", "server.js"]
</ubicación>
Para construir la imagen y luego ejecutarla se usan los siguientes comandos:
docker build -t chat .
docker run -d --name chat-app -p 9000:9000 chat
El resultado es un proceso Node.js en un contenedor que ejecuta un servidor socket.io. Este contenedor se ejecuta en AWS Fargate y se expone a través de una ELB.
Código fuente
https://github.com/crperz/chat-app