# NestJS y WebSockets en 2026: Tiempo Real, Gateway y Preguntas de Entrevista > Domina WebSockets en NestJS con patrones Gateway, integración Socket.IO, autenticación, manejo de errores y preguntas comunes de entrevista para 2026. - Published: 2026-08-10 - Updated: 2026-08-10 - Author: Anthony Fillion-Maillet - Reading time: 5 min --- Los WebSockets de NestJS proporcionan un enfoque estructurado para la comunicación en tiempo real utilizando el patrón Gateway. A diferencia de las implementaciones WebSocket básicas, NestJS abstrae la complejidad mediante decoradores e integra perfectamente con el sistema de inyección de dependencias. > **Definición Rápida** > > Un WebSocket Gateway en NestJS es una clase decorada con `@WebSocketGateway()` que maneja la comunicación bidireccional entre cliente y servidor. Soporta múltiples adaptadores (Socket.IO, ws) y se integra con Guards, Pipes e Interceptors de NestJS. ## Configuración de un WebSocket Gateway con Socket.IO El adaptador predeterminado en NestJS utiliza [Socket.IO](https://socket.io/docs/v4/), que proporciona reconexión automática, soporte para rooms y fallback a HTTP long-polling. La instalación requiere el paquete específico de la plataforma junto con el módulo principal de WebSockets. ```bash # terminal npm install @nestjs/websockets @nestjs/platform-socket.io socket.io ``` Un gateway básico escucha mensajes entrantes y puede transmitir respuestas a los clientes conectados. ```typescript // chat.gateway.ts import { WebSocketGateway, WebSocketServer, SubscribeMessage, MessageBody, ConnectedSocket, } from '@nestjs/websockets'; import { Server, Socket } from 'socket.io'; @WebSocketGateway({ cors: { origin: '*' }, // Configura CORS para clientes del navegador }) export class ChatGateway { @WebSocketServer() server: Server; // Acceso al servidor Socket.IO subyacente @SubscribeMessage('message') // Escucha eventos 'message' handleMessage( @MessageBody() data: { text: string; room: string }, @ConnectedSocket() client: Socket, ): void { // Transmite a todos los clientes en la room excepto el remitente client.to(data.room).emit('message', { text: data.text, senderId: client.id, timestamp: Date.now(), }); } } ``` El decorador `@SubscribeMessage` vincula un método a un nombre de evento específico. `@MessageBody()` extrae el payload, mientras que `@ConnectedSocket()` proporciona acceso al socket del cliente para respuestas dirigidas. ## Hooks del Ciclo de Vida para Gestión de Conexiones Los gateways de NestJS implementan interfaces de ciclo de vida para manejar conexiones y desconexiones de clientes. Estos hooks permiten la limpieza de recursos, seguimiento de presencia y validación de conexiones. ```typescript // presence.gateway.ts import { WebSocketGateway, OnGatewayConnection, OnGatewayDisconnect, OnGatewayInit, } from '@nestjs/websockets'; import { Server, Socket } from 'socket.io'; import { Logger } from '@nestjs/common'; @WebSocketGateway() export class PresenceGateway implements OnGatewayInit, OnGatewayConnection, OnGatewayDisconnect { private readonly logger = new Logger(PresenceGateway.name); private connectedUsers = new Map(); afterInit(server: Server): void { // Se llama una vez cuando el gateway se inicializa this.logger.log('WebSocket Gateway inicializado'); } handleConnection(client: Socket): void { // Rastrea nuevas conexiones this.connectedUsers.set(client.id, { joinedAt: new Date() }); this.logger.log(`Cliente conectado: ${client.id}`); } handleDisconnect(client: Socket): void { // Limpieza al desconectar this.connectedUsers.delete(client.id); this.logger.log(`Cliente desconectado: ${client.id}`); } } ``` Las tres interfaces de ciclo de vida sirven propósitos distintos: `OnGatewayInit` se ejecuta una vez al inicio, `OnGatewayConnection` se activa por cada conexión de cliente, y `OnGatewayDisconnect` maneja la limpieza cuando los clientes se van. ## Autenticación con Guards de WebSocket Las conexiones WebSocket requieren validación de autenticación antes de permitir acceso a eventos protegidos. Los Guards de NestJS funcionan con gateways, aunque el contexto de ejecución difiere de las solicitudes HTTP. La [documentación oficial de WebSockets de NestJS](https://docs.nestjs.com/websockets/gateways) cubre la integración de guards en detalle. ```typescript // ws-auth.guard.ts import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common'; import { WsException } from '@nestjs/websockets'; import { JwtService } from '@nestjs/jwt'; import { Socket } from 'socket.io'; @Injectable() export class WsAuthGuard implements CanActivate { constructor(private jwtService: JwtService) {} canActivate(context: ExecutionContext): boolean { const client: Socket = context.switchToWs().getClient(); // Extrae el token del handshake auth o query params const token = client.handshake.auth?.token || client.handshake.query?.token; if (!token) { throw new WsException('Token de autenticación faltante'); } try { const payload = this.jwtService.verify(token as string); // Adjunta datos del usuario al socket para uso posterior client.data.user = payload; return true; } catch { throw new WsException('Token inválido'); } } } ``` El guard se aplica a la clase gateway o a handlers de mensajes individuales usando el decorador `@UseGuards()`. La clase `WsException` lanza errores que el cliente recibe a través del evento error de Socket.IO. ```typescript // secure-chat.gateway.ts import { UseGuards } from '@nestjs/common'; import { WebSocketGateway, SubscribeMessage } from '@nestjs/websockets'; import { WsAuthGuard } from './ws-auth.guard'; @WebSocketGateway() @UseGuards(WsAuthGuard) // Protege todos los handlers en este gateway export class SecureChatGateway { @SubscribeMessage('privateMessage') handlePrivateMessage(): void { // Solo clientes autenticados llegan a este handler } } ``` Para preguntas de autenticación a nivel de módulo, consulta el [módulo de entrevista de autenticación y JWT de NestJS](/technologies/node-nestjs/interview-questions/authentication-jwt) que cubre estrategias JWT y gestión de sesiones. ## Patrones de Broadcasting Basados en Rooms Las rooms de Socket.IO permiten la entrega dirigida de mensajes a subconjuntos de clientes conectados. Los casos de uso comunes incluyen salas de chat, lobbies de juegos y funciones de colaboración en vivo. ```typescript // room.gateway.ts import { WebSocketGateway, SubscribeMessage, ConnectedSocket, MessageBody, WebSocketServer, } from '@nestjs/websockets'; import { Server, Socket } from 'socket.io'; @WebSocketGateway() export class RoomGateway { @WebSocketServer() server: Server; @SubscribeMessage('joinRoom') handleJoinRoom( @MessageBody() roomId: string, @ConnectedSocket() client: Socket, ): { event: string; data: string } { // Agrega el cliente a la room especificada client.join(roomId); // Notifica a otros en la room client.to(roomId).emit('userJoined', { userId: client.id }); return { event: 'joinedRoom', data: roomId }; } @SubscribeMessage('leaveRoom') handleLeaveRoom( @MessageBody() roomId: string, @ConnectedSocket() client: Socket, ): void { client.leave(roomId); client.to(roomId).emit('userLeft', { userId: client.id }); } @SubscribeMessage('roomBroadcast') handleRoomBroadcast( @MessageBody() payload: { roomId: string; message: string }, ): void { // Envía a todos los clientes en la room, incluyendo al remitente this.server.to(payload.roomId).emit('roomMessage', payload.message); } } ``` La distinción entre `client.to(room).emit()` y `server.to(room).emit()` es importante: el primero excluye al remitente, mientras que el segundo incluye a todos los miembros de la room. ## Manejo de Errores con Filtros de Excepción Las excepciones WebSocket requieren filtros dedicados ya que los filtros de excepción HTTP no aplican a contextos de gateway. Los filtros personalizados capturan `WsException` y formatean respuestas de error para los clientes. ```typescript // ws-exception.filter.ts import { Catch, ArgumentsHost, ExceptionFilter } from '@nestjs/common'; import { WsException } from '@nestjs/websockets'; import { Socket } from 'socket.io'; @Catch(WsException) export class WsExceptionFilter implements ExceptionFilter { catch(exception: WsException, host: ArgumentsHost): void { const client: Socket = host.switchToWs().getClient(); const error = exception.getError(); // Envía error estructurado al cliente client.emit('error', { type: 'WsException', message: typeof error === 'string' ? error : error, timestamp: new Date().toISOString(), }); } } ``` Los filtros se aplican a nivel de gateway para un manejo consistente de errores en todos los handlers de mensajes. ```typescript // filtered.gateway.ts import { UseFilters } from '@nestjs/common'; import { WebSocketGateway } from '@nestjs/websockets'; import { WsExceptionFilter } from './ws-exception.filter'; @WebSocketGateway() @UseFilters(WsExceptionFilter) export class FilteredGateway { // Todos los handlers se benefician del manejo centralizado de errores } ``` Este patrón refleja la filosofía de NestJS de decoradores y filtros descrita en el [módulo de middleware e interceptors](/technologies/node-nestjs/interview-questions/middleware-interceptors). ## Escalando WebSockets con Adaptador Redis Los despliegues WebSocket de un solo servidor fallan cuando el balanceo de carga distribuye clientes entre múltiples instancias. El [adaptador Redis de Socket.IO](https://socket.io/docs/v4/redis-adapter/) sincroniza eventos entre instancias a través de un mecanismo pub/sub. ```typescript // app.module.ts import { Module } from '@nestjs/common'; import { createAdapter } from '@socket.io/redis-adapter'; import { createClient } from 'redis'; import { ChatGateway } from './chat.gateway'; @Module({ providers: [ ChatGateway, { provide: 'REDIS_ADAPTER', useFactory: async () => { const pubClient = createClient({ url: process.env.REDIS_URL }); const subClient = pubClient.duplicate(); await Promise.all([pubClient.connect(), subClient.connect()]); return createAdapter(pubClient, subClient); }, }, ], }) export class AppModule {} ``` El gateway luego usa el adaptador para comunicación entre instancias. ```typescript // scalable.gateway.ts import { WebSocketGateway, WebSocketServer, OnGatewayInit, } from '@nestjs/websockets'; import { Inject } from '@nestjs/common'; import { Server } from 'socket.io'; import { Adapter } from 'socket.io-adapter'; @WebSocketGateway() export class ScalableGateway implements OnGatewayInit { @WebSocketServer() server: Server; constructor(@Inject('REDIS_ADAPTER') private redisAdapter: Adapter) {} afterInit(): void { // Adjunta el adaptador Redis para soporte multi-instancia this.server.adapter(this.redisAdapter as any); } } ``` Con el adaptador Redis, un mensaje emitido en una instancia del servidor llega a los clientes conectados a cualquier instancia del cluster. ## Preguntas Comunes de Entrevista sobre WebSockets en NestJS Las entrevistas técnicas frecuentemente exploran la comprensión de decisiones de arquitectura en tiempo real y detalles de implementación específicos de NestJS. > **Frecuentemente Preguntado** > > **¿Cómo maneja NestJS la autenticación WebSocket de manera diferente a HTTP?** > > El middleware HTTP no se ejecuta para conexiones WebSocket. La autenticación ocurre durante la fase de handshake o a través de Guards aplicados al gateway. La validación del token típicamente ocurre en `handleConnection()` o un Guard personalizado que lee desde `socket.handshake.auth`. **¿Cuál es la diferencia entre la configuración de puerto de `@WebSocketGateway()` y el puerto principal de la aplicación?** Por defecto, los gateways WebSocket comparten el puerto del servidor HTTP. Especificar un puerto en `@WebSocketGateway(3001)` crea un servidor WebSocket separado en ese puerto. Los puertos compartidos simplifican el despliegue pero requieren enrutamiento basado en rutas (`/socket.io`) al usar proxies reversos. **¿Cómo se prueban los gateways WebSocket en NestJS?** Las utilidades de testing de NestJS soportan pruebas de gateway a través de `Test.createTestingModule()`. La biblioteca [socket.io-client](https://github.com/socketio/socket.io-client) se conecta al servidor de pruebas. Los hooks de ciclo de vida y handlers de mensajes se prueban emitiendo eventos y verificando respuestas o efectos secundarios. ```typescript // chat.gateway.spec.ts import { Test } from '@nestjs/testing'; import { INestApplication } from '@nestjs/common'; import { io, Socket } from 'socket.io-client'; import { ChatGateway } from './chat.gateway'; describe('ChatGateway', () => { let app: INestApplication; let client: Socket; beforeAll(async () => { const module = await Test.createTestingModule({ providers: [ChatGateway], }).compile(); app = module.createNestApplication(); await app.listen(3000); client = io('http://localhost:3000'); }); afterAll(async () => { client.disconnect(); await app.close(); }); it('recibe confirmación de mensaje', (done) => { client.emit('message', { text: 'test', room: 'lobby' }); client.on('message', (data) => { expect(data.text).toBe('test'); done(); }); }); }); ``` **¿Cuándo usar el adaptador ws en lugar de Socket.IO?** El adaptador de la [biblioteca ws](https://github.com/websockets/ws) (`@nestjs/platform-ws`) ofrece menor overhead para aplicaciones que no necesitan características de Socket.IO como reconexión automática, rooms o transportes de fallback. Los sistemas de trading de alta frecuencia y servidores de juegos a menudo prefieren ws por su latencia reducida. Para conceptos más amplios de arquitectura NestJS, el artículo relacionado sobre [Guards, Interceptors y Arquitectura Modular](/blog/node-nestjs/nestjs-guards-interceptors-modular-architecture) cubre cómo estos patrones se integran a través de contextos HTTP y WebSocket. ## Conclusión - Los WebSocket Gateways se integran con inyección de dependencias, Guards y Filters de NestJS para patrones consistentes entre HTTP y endpoints de tiempo real - Los hooks de ciclo de vida (`OnGatewayConnection`, `OnGatewayDisconnect`) gestionan el seguimiento de presencia y limpieza de recursos - Los flujos de autenticación difieren de HTTP; la validación del token ocurre durante el handshake o a través de Guards WebSocket dedicados - El broadcasting basado en rooms con Socket.IO permite mensajería dirigida sin gestionar listas de sockets manualmente - El adaptador Redis resuelve el escalado horizontal sincronizando eventos entre múltiples instancias del servidor - Los filtros de excepción requieren implementaciones específicas de WebSocket usando `WsException` y filtros personalizados --- Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack. HTML version of this page: https://sharpskill.dev/es/blog/node-nestjs/nestjs-websockets-real-time-gateway-best-practices