NestJS e WebSockets em 2026: Tempo Real, Gateway e Perguntas de Entrevista
Domine WebSockets no NestJS com padrões Gateway, integração Socket.IO, autenticação, tratamento de erros e perguntas comuns de entrevista para 2026.

Os WebSockets do NestJS fornecem uma abordagem estruturada para comunicação em tempo real utilizando o padrão Gateway. Diferente das implementações WebSocket brutas, o NestJS abstrai a complexidade através de decorators e integra perfeitamente com o sistema de injeção de dependências.
Um WebSocket Gateway no NestJS é uma classe decorada com @WebSocketGateway() que gerencia a comunicação bidirecional entre cliente e servidor. Suporta múltiplos adaptadores (Socket.IO, ws) e integra com Guards, Pipes e Interceptors do NestJS.
Configurando um WebSocket Gateway com Socket.IO
O adaptador padrão no NestJS utiliza o Socket.IO, que fornece reconexão automática, suporte a rooms e fallback para HTTP long-polling. A instalação requer o pacote específico da plataforma junto com o módulo principal de WebSockets.
# terminal
npm install @nestjs/websockets @nestjs/platform-socket.io socket.ioUm gateway básico escuta mensagens recebidas e pode transmitir respostas para os clientes conectados.
import {
WebSocketGateway,
WebSocketServer,
SubscribeMessage,
MessageBody,
ConnectedSocket,
} from '@nestjs/websockets';
import { Server, Socket } from 'socket.io';
@WebSocketGateway({
cors: { origin: '*' }, // Configura CORS para clientes do navegador
})
export class ChatGateway {
@WebSocketServer()
server: Server; // Acesso ao servidor Socket.IO subjacente
@SubscribeMessage('message') // Escuta eventos 'message'
handleMessage(
@MessageBody() data: { text: string; room: string },
@ConnectedSocket() client: Socket,
): void {
// Transmite para todos os clientes na room exceto o remetente
client.to(data.room).emit('message', {
text: data.text,
senderId: client.id,
timestamp: Date.now(),
});
}
}O decorator @SubscribeMessage vincula um método a um nome de evento específico. O @MessageBody() extrai o payload, enquanto @ConnectedSocket() fornece acesso ao socket do cliente para respostas direcionadas.
Hooks de Ciclo de Vida para Gerenciamento de Conexões
Os gateways do NestJS implementam interfaces de ciclo de vida para gerenciar conexões e desconexões de clientes. Esses hooks permitem limpeza de recursos, rastreamento de presença e validação de conexões.
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<string, { joinedAt: Date }>();
afterInit(server: Server): void {
// Chamado uma vez quando o gateway inicializa
this.logger.log('WebSocket Gateway inicializado');
}
handleConnection(client: Socket): void {
// Rastreia novas conexões
this.connectedUsers.set(client.id, { joinedAt: new Date() });
this.logger.log(`Cliente conectado: ${client.id}`);
}
handleDisconnect(client: Socket): void {
// Limpeza na desconexão
this.connectedUsers.delete(client.id);
this.logger.log(`Cliente desconectado: ${client.id}`);
}
}As três interfaces de ciclo de vida servem propósitos distintos: OnGatewayInit executa uma vez na inicialização, OnGatewayConnection dispara por conexão de cliente, e OnGatewayDisconnect gerencia a limpeza quando os clientes saem.
Autenticação com Guards de WebSocket
As conexões WebSocket requerem validação de autenticação antes de permitir acesso a eventos protegidos. Os Guards do NestJS funcionam com gateways, embora o contexto de execução difira das requisições HTTP. A documentação oficial de WebSockets do NestJS cobre a integração de guards em detalhes.
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();
// Extrai o token do handshake auth ou query params
const token =
client.handshake.auth?.token ||
client.handshake.query?.token;
if (!token) {
throw new WsException('Token de autenticação ausente');
}
try {
const payload = this.jwtService.verify(token as string);
// Anexa dados do usuário ao socket para uso posterior
client.data.user = payload;
return true;
} catch {
throw new WsException('Token inválido');
}
}
}O guard é aplicado à classe gateway ou a handlers de mensagem individuais usando o decorator @UseGuards(). A classe WsException lança erros que o cliente recebe através do evento error do Socket.IO.
import { UseGuards } from '@nestjs/common';
import { WebSocketGateway, SubscribeMessage } from '@nestjs/websockets';
import { WsAuthGuard } from './ws-auth.guard';
@WebSocketGateway()
@UseGuards(WsAuthGuard) // Protege todos os handlers neste gateway
export class SecureChatGateway {
@SubscribeMessage('privateMessage')
handlePrivateMessage(): void {
// Apenas clientes autenticados alcançam este handler
}
}Para perguntas de autenticação em nível de módulo, consulte o módulo de entrevista sobre autenticação e JWT do NestJS que cobre estratégias JWT e gerenciamento de sessões.
Pronto para mandar bem nas entrevistas de Node.js / NestJS?
Pratique com nossos simuladores interativos, flashcards e testes tecnicos.
Padrões de Broadcasting Baseados em Rooms
As rooms do Socket.IO permitem entrega direcionada de mensagens para subconjuntos de clientes conectados. Os casos de uso comuns incluem salas de chat, lobbies de jogos e recursos de colaboração em tempo real.
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 } {
// Adiciona o cliente à room especificada
client.join(roomId);
// Notifica outros na 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 {
// Envia para todos os clientes na room, incluindo o remetente
this.server.to(payload.roomId).emit('roomMessage', payload.message);
}
}A distinção entre client.to(room).emit() e server.to(room).emit() é importante: o primeiro exclui o remetente, enquanto o segundo inclui todos os membros da room.
Tratamento de Erros com Filtros de Exceção
As exceções WebSocket requerem filtros dedicados já que os filtros de exceção HTTP não se aplicam a contextos de gateway. Filtros personalizados capturam WsException e formatam respostas de erro para os clientes.
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();
// Envia erro estruturado para o cliente
client.emit('error', {
type: 'WsException',
message: typeof error === 'string' ? error : error,
timestamp: new Date().toISOString(),
});
}
}Os filtros são aplicados no nível do gateway para tratamento consistente de erros em todos os handlers de mensagem.
import { UseFilters } from '@nestjs/common';
import { WebSocketGateway } from '@nestjs/websockets';
import { WsExceptionFilter } from './ws-exception.filter';
@WebSocketGateway()
@UseFilters(WsExceptionFilter)
export class FilteredGateway {
// Todos os handlers se beneficiam do tratamento centralizado de erros
}Este padrão reflete a filosofia do NestJS de decorators e filtros descrita no módulo de middleware e interceptors.
Escalando WebSockets com Adaptador Redis
Implantações WebSocket de servidor único falham quando o balanceamento de carga distribui clientes entre múltiplas instâncias. O adaptador Redis do Socket.IO sincroniza eventos entre instâncias através de um mecanismo pub/sub.
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 {}O gateway então usa o adaptador para comunicação entre instâncias.
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 {
// Anexa o adaptador Redis para suporte multi-instância
this.server.adapter(this.redisAdapter as any);
}
}Com o adaptador Redis, uma mensagem emitida em uma instância do servidor alcança clientes conectados a qualquer instância do cluster.
Perguntas Comuns de Entrevista sobre WebSockets no NestJS
Entrevistas técnicas frequentemente exploram a compreensão de decisões de arquitetura em tempo real e detalhes de implementação específicos do NestJS.
Como o NestJS trata a autenticação WebSocket diferente do HTTP?
O middleware HTTP não executa para conexões WebSocket. A autenticação acontece durante a fase de handshake ou através de Guards aplicados ao gateway. A validação do token tipicamente ocorre em handleConnection() ou um Guard personalizado que lê de socket.handshake.auth.
Qual é a diferença entre a configuração de porta do @WebSocketGateway() e a porta principal da aplicação?
Por padrão, os gateways WebSocket compartilham a porta do servidor HTTP. Especificar uma porta em @WebSocketGateway(3001) cria um servidor WebSocket separado nessa porta. Portas compartilhadas simplificam a implantação mas requerem roteamento baseado em caminho (/socket.io) ao usar proxies reversos.
Como testar gateways WebSocket no NestJS?
As utilidades de teste do NestJS suportam testes de gateway através de Test.createTestingModule(). A biblioteca socket.io-client conecta ao servidor de teste. Os hooks de ciclo de vida e handlers de mensagem são testados emitindo eventos e verificando respostas ou efeitos colaterais.
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('recebe confirmação de mensagem', (done) => {
client.emit('message', { text: 'test', room: 'lobby' });
client.on('message', (data) => {
expect(data.text).toBe('test');
done();
});
});
});Quando usar o adaptador ws ao invés do Socket.IO?
O adaptador da biblioteca ws (@nestjs/platform-ws) oferece menor overhead para aplicações que não precisam de recursos do Socket.IO como reconexão automática, rooms ou transportes de fallback. Sistemas de trading de alta frequência e servidores de jogos frequentemente preferem ws pela latência reduzida.
Para conceitos mais amplos de arquitetura NestJS, o artigo relacionado sobre Guards, Interceptors e Arquitetura Modular cobre como esses padrões se integram através de contextos HTTP e WebSocket.
Conclusão
- Os WebSocket Gateways integram com injeção de dependências, Guards e Filters do NestJS para padrões consistentes entre HTTP e endpoints em tempo real
- Os hooks de ciclo de vida (
OnGatewayConnection,OnGatewayDisconnect) gerenciam rastreamento de presença e limpeza de recursos - Os fluxos de autenticação diferem do HTTP; a validação do token ocorre durante o handshake ou através de Guards WebSocket dedicados
- O broadcasting baseado em rooms com Socket.IO permite mensagens direcionadas sem gerenciar listas de sockets manualmente
- O adaptador Redis resolve a escalabilidade horizontal sincronizando eventos entre múltiplas instâncias do servidor
- Os filtros de exceção requerem implementações específicas de WebSocket usando
WsExceptione filtros personalizados
Comece a praticar!
Teste seus conhecimentos com nossos simuladores de entrevista e testes tecnicos.

Escrito por
Anthony Fillion-MailletDesenvolvedor fullstack, fundador da SharpSkill
Desenvolvedor fullstack há mais de 10 anos. Dirige a SharpSkill e responde por tudo o que é publicado aqui.
Atualizado em 10 de agosto de 2026
Compartilhar
Artigos relacionados

NestJS e GraphQL em 2026: Schemas, Resolvers e Perguntas de Entrevista
Guia completo sobre a integração do NestJS com GraphQL: abordagens code-first e schema-first, criação de resolvers, e preparação para entrevistas técnicas em 2026.

NestJS e TypeORM em 2026: migrations, relações e perguntas de entrevista
Dominar a integração do NestJS com o TypeORM usando as migrations do TypeORM 1.0, as relações entre entidades, o padrão repository e as perguntas de entrevista comuns para desenvolvedores backend.

Node.js 24 em 2026: URLPattern, Permission Model e perguntas de entrevista
O Node.js 24 LTS traz um Permission Model estável, URLPattern global, gerenciamento explícito de recursos com using/await using e V8 13.6. Uma análise aprofundada dos recursos que importam em produção e em entrevistas.