# NestJS en WebSockets in 2026: Real-Time Communicatie, Gateway en Sollicitatievragen > WebSockets in NestJS beheersen met Gateway-patronen, Socket.IO-integratie, authenticatie, foutafhandeling en veelgestelde sollicitatievragen voor 2026. - Published: 2026-08-10 - Updated: 2026-08-10 - Author: Anthony Fillion-Maillet - Reading time: 5 min --- NestJS WebSockets bieden een gestructureerde aanpak voor real-time communicatie met behulp van het Gateway-patroon. In tegenstelling tot ruwe WebSocket-implementaties abstraheert NestJS de complexiteit door middel van decorators en integreert het naadloos met het dependency injection-systeem. > **Snelle Definitie** > > Een WebSocket Gateway in NestJS is een klasse die is gedecoreerd met `@WebSocketGateway()` en bidirectionele communicatie tussen client en server afhandelt. Het ondersteunt meerdere adapters (Socket.IO, ws) en integreert met NestJS Guards, Pipes en Interceptors. ## Een WebSocket Gateway Opzetten met Socket.IO De standaard adapter in NestJS gebruikt [Socket.IO](https://socket.io/docs/v4/), dat automatische herverbinding, room-ondersteuning en fallback naar HTTP long-polling biedt. De installatie vereist het platformspecifieke pakket naast de core WebSockets-module. ```bash # terminal npm install @nestjs/websockets @nestjs/platform-socket.io socket.io ``` Een basis gateway luistert naar inkomende berichten en kan antwoorden broadcasten naar verbonden clients. ```typescript // chat.gateway.ts import { WebSocketGateway, WebSocketServer, SubscribeMessage, MessageBody, ConnectedSocket, } from '@nestjs/websockets'; import { Server, Socket } from 'socket.io'; @WebSocketGateway({ cors: { origin: '*' }, // Configure CORS for browser clients }) export class ChatGateway { @WebSocketServer() server: Server; // Access to the underlying Socket.IO server @SubscribeMessage('message') // Listen for 'message' events handleMessage( @MessageBody() data: { text: string; room: string }, @ConnectedSocket() client: Socket, ): void { // Broadcast to all clients in the room except sender client.to(data.room).emit('message', { text: data.text, senderId: client.id, timestamp: Date.now(), }); } } ``` De `@SubscribeMessage`-decorator bindt een methode aan een specifieke eventnaam. `@MessageBody()` extraheert de payload, terwijl `@ConnectedSocket()` toegang biedt tot de client socket voor gerichte antwoorden. ## Lifecycle Hooks voor Verbindingsbeheer NestJS gateways implementeren lifecycle-interfaces voor het afhandelen van client-verbindingen en -disconnecties. Deze hooks maken resource cleanup, aanwezigheidstracking en verbindingsvalidatie mogelijk. ```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 { // Called once when the gateway initializes this.logger.log('WebSocket Gateway initialized'); } handleConnection(client: Socket): void { // Track new connections this.connectedUsers.set(client.id, { joinedAt: new Date() }); this.logger.log(`Client connected: ${client.id}`); } handleDisconnect(client: Socket): void { // Cleanup on disconnect this.connectedUsers.delete(client.id); this.logger.log(`Client disconnected: ${client.id}`); } } ``` De drie lifecycle-interfaces hebben verschillende doeleinden: `OnGatewayInit` wordt eenmalig uitgevoerd bij opstarten, `OnGatewayConnection` wordt geactiveerd per client-verbinding, en `OnGatewayDisconnect` handelt cleanup af wanneer clients vertrekken. ## Authenticatie met WebSocket Guards WebSocket-verbindingen vereisen authenticatievalidatie voordat toegang tot beschermde events wordt verleend. NestJS Guards werken met gateways, hoewel de uitvoeringscontext verschilt van HTTP-verzoeken. De officiële [NestJS WebSockets-documentatie](https://docs.nestjs.com/websockets/gateways) behandelt guard-integratie in detail. ```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(); // Extract token from handshake auth or query params const token = client.handshake.auth?.token || client.handshake.query?.token; if (!token) { throw new WsException('Missing authentication token'); } try { const payload = this.jwtService.verify(token as string); // Attach user data to socket for later use client.data.user = payload; return true; } catch { throw new WsException('Invalid token'); } } } ``` Pas de guard toe op de gateway-klasse of individuele message handlers met behulp van de `@UseGuards()`-decorator. De `WsException`-klasse gooit fouten die de client ontvangt via het Socket.IO error event. ```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) // Protect all handlers in this gateway export class SecureChatGateway { @SubscribeMessage('privateMessage') handlePrivateMessage(): void { // Only authenticated clients reach this handler } } ``` Voor vragen over authenticatie op moduleniveau biedt de [NestJS authenticatie interview module](/technologies/node-nestjs/interview-questions/authentication-jwt) informatie over JWT-strategieën en sessiebeheer. ## Room-gebaseerde Broadcasting Patronen Socket.IO rooms maken gerichte berichtbezorging naar subsets van verbonden clients mogelijk. Veelvoorkomende use cases zijn chatrooms, game lobbies en live samenwerkingsfuncties. ```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 } { // Add client to the specified room client.join(roomId); // Notify others in the 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 { // Send to all clients in room, including sender this.server.to(payload.roomId).emit('roomMessage', payload.message); } } ``` Het onderscheid tussen `client.to(room).emit()` en `server.to(room).emit()` is belangrijk: de eerste sluit de verzender uit, terwijl de laatste alle room-leden omvat. ## Foutafhandeling met Exception Filters WebSocket-excepties vereisen speciale filters omdat HTTP exception filters niet van toepassing zijn op gateway-contexten. Aangepaste filters vangen `WsException` af en formatteren foutresponses voor clients. ```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(); // Send structured error to client client.emit('error', { type: 'WsException', message: typeof error === 'string' ? error : error, timestamp: new Date().toISOString(), }); } } ``` Pas filters toe op gateway-niveau voor consistente foutafhandeling over alle message handlers. ```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 { // All handlers benefit from centralized error handling } ``` Dit patroon weerspiegelt de NestJS-filosofie van decorators en filters die wordt beschreven in de [middleware en interceptors module](/technologies/node-nestjs/interview-questions/middleware-interceptors). ## WebSockets Schalen met Redis Adapter Single-server WebSocket deployments falen wanneer load balancing clients over meerdere instanties distribueert. De [Socket.IO Redis adapter](https://socket.io/docs/v4/redis-adapter/) synchroniseert events over instanties via een pub/sub-mechanisme. ```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 {} ``` De gateway gebruikt vervolgens de adapter voor cross-instance communicatie. ```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 { // Attach Redis adapter for multi-instance support this.server.adapter(this.redisAdapter as any); } } ``` Met de Redis adapter bereikt een bericht dat op één server-instantie wordt uitgezonden, clients die verbonden zijn met elke instantie in het cluster. ## Veelgestelde Sollicitatievragen over NestJS WebSockets Technische sollicitatiegesprekken peilen vaak naar begrip van real-time architectuurbeslissingen en NestJS-specifieke implementatiedetails. > **Veelgestelde Vraag** > > **Hoe behandelt NestJS WebSocket-authenticatie anders dan HTTP?** > > HTTP middleware wordt niet uitgevoerd voor WebSocket-verbindingen. Authenticatie vindt plaats tijdens de handshake-fase of via Guards die op de gateway worden toegepast. Token-validatie gebeurt doorgaans in `handleConnection()` of een aangepaste Guard die leest uit `socket.handshake.auth`. **Wat is het verschil tussen de poortconfiguratie van `@WebSocketGateway()` en de hoofdapplicatiepoort?** Standaard delen WebSocket Gateways de HTTP-serverpoort. Het specificeren van een poort in `@WebSocketGateway(3001)` creëert een aparte WebSocket-server op die poort. Gedeelde poorten vereenvoudigen deployment maar vereisen pad-gebaseerde routing (`/socket.io`) bij gebruik van reverse proxies. **Hoe test je WebSocket Gateways in NestJS?** NestJS testing utilities ondersteunen gateway-testing via `Test.createTestingModule()`. De [socket.io-client](https://github.com/socketio/socket.io-client) bibliotheek verbindt met de testserver. Lifecycle hooks en message handlers worden getest door events te emitteren en te asserteren op responses of side effects. ```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('receives message acknowledgment', (done) => { client.emit('message', { text: 'test', room: 'lobby' }); client.on('message', (data) => { expect(data.text).toBe('test'); done(); }); }); }); ``` **Wanneer moet je de ws adapter gebruiken in plaats van Socket.IO?** De [ws library](https://github.com/websockets/ws) adapter (`@nestjs/platform-ws`) biedt lagere overhead voor applicaties die Socket.IO-features zoals automatische herverbinding, rooms of fallback transports niet nodig hebben. High-frequency trading systemen en game servers geven vaak de voorkeur aan ws voor verminderde latency. Voor bredere NestJS-architectuurconcepten behandelt het gerelateerde artikel over [Guards, Interceptors en Modulaire Architectuur](/blog/node-nestjs/nestjs-guards-interceptors-modular-architecture) hoe deze patronen integreren over HTTP- en WebSocket-contexten. ## Conclusie - WebSocket Gateways integreren met NestJS dependency injection, Guards en Filters voor consistente patronen over HTTP- en real-time endpoints - Lifecycle hooks (`OnGatewayConnection`, `OnGatewayDisconnect`) beheren aanwezigheidstracking en resource cleanup - Authenticatiestromen verschillen van HTTP; token-validatie vindt plaats tijdens de handshake of via speciale WebSocket Guards - Room-gebaseerde broadcasting met Socket.IO maakt gerichte messaging mogelijk zonder handmatig socket-lijsten te beheren - Redis adapter lost horizontale schaalbaarheid op door events te synchroniseren over meerdere server-instanties - Exception filters vereisen WebSocket-specifieke implementaties met `WsException` en aangepaste filters --- Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack. HTML version of this page: https://sharpskill.dev/nl/blog/node-nestjs/nestjs-websockets-real-time-gateway-best-practices