Crear un servidor de Nest con WebSocket y un chat
- Clonar proyecto
git clone https://github.com/Klerith/cf-websocket-homework.git
- Navegar dentro de la carpeta e instalar dependencias
cd <directorio>
npm install
- Ejecutar el servidor
npm run start:dev
- Probar las rutas: Login y Chat
- Instalar dependencias (más información aquí)
npm i --save @nestjs/websockets @nestjs/platform-socket.io
- Crear el módulo, gateway y servicio, usar el CLI de Nest y seleccionar la opción de WebSockets, pero decir que NO a la parte del CRUD
nest g res chat --no-spec
Los gateways son similares a los controladores para Rest. Se encargan de recibir las peticiones y enviar las respuestas pero mediante websockets.
- En el chat.gateway.ts, crear la siguiente propiedad y decorarla:
@WebSocketServer()
public server: Server;
-
WebSocketServer viene de '@nestjs/websockets'
-
Server viene de 'socket.io'
- A nuestro ChatGateway, implementar la interfaz OnGatewayInit y agregar el método onModuleInit:
export class ChatGateway implements OnModuleInit {
@WebSocketServer()
public server: Server;
onModuleInit() {
// ...
}
}
- OnModuleInit viene de '@nestjs/common'
- En el método onModuleInit, agregar el siguiente código:
onModuleInit() {
this.server.on('connection', (socket) => {
console.log('New client connected');
});
}
-
Abrir la página del chat (localhost:3000/chat) y abrir la consola del navegador.
-
Abrir el archivo
public/js/chat.js
y agregar el siguiente código:
const socket = io();
- io viene de 'socket.io-client' que ya está importado en el chat.html al final del archivo
- En la consola de NEST, debería aparecer el mensaje de New client connected
- En el chat.gateway.ts, agregar el siguiente código en el método onModuleInit:
@SubscribeMessage('send-message')
handleMessage(
@MessageBody() message: string,
@ConnectedSocket() client: Socket
) {
if ( !message ) return;
this.server.emit(
'on-message',
{ userId: client.id, message: message }
)
}
- Realizar las importaciones necesarias de los decoradores usados.
- Socket viene de 'socket.io'
- En el chat.js, al inicio del archivo, agregar el siguiente código:
const form = document.querySelector('form');
const input = document.querySelector('input');
const chatElement = document.querySelector('#chat');
- Estas son nuestras referencias a los elementos HTML que necesitaremos
- Crear una función para renderizar los mensajes en el chat:
const renderMessage = (payload) => {
const { userId, message } = payload;
// Crear un DIV Element
const divElement = document.createElement('div');
// Agregar la clase de mensaje
divElement.classList.add('message');
// Si el UserID NO es el mío, agregar "incoming"
if ( userId !== socket.id ) {
divElement.classList.add('incoming');
}
// Agregar el mensaje al DIV
divElement.innerHTML = message;
// Agregar el DIV al chat
chatElement.appendChild(divElement);
}
- Agregar el siguiente código para escuchar el evento on-message:
socket.on('on-message', (payload) => {
renderMessage(payload);
});
- Alternativo
socket.on('on-message', renderMessage);
- Agregar un listener en el formulario para escuchar el evento submit:
form.addEventListener( 'submit', ( event ) => {
event.preventDefault();
const message = input.value;
input.value = '';
socket.emit( 'send-message', message );
} );
-
Importante: Noten que en el Gateway del servidor, tenemos este código
@SubscribeMessage('send-message')
el cual escucha el evento que estamos mandando desde el cliente. -
Es importante que el nombre del evento sea el mismo en ambos lados.
-
Abran otra instancia del navegador web y manden mensajes desde ambos lados.