# NestJS et WebSockets en 2026 : Temps Réel, Gateway et Questions d'Entretien > Maîtrisez les WebSockets NestJS avec les patterns Gateway, l'intégration Socket.IO, l'authentification, la gestion des erreurs et les questions d'entretien courantes pour 2026. - Published: 2026-08-10 - Updated: 2026-08-10 - Author: SharpSkill - Reading time: 5 min --- Les WebSockets NestJS offrent une approche structurée de la communication temps réel grâce au pattern Gateway. Contrairement aux implémentations WebSocket brutes, NestJS abstrait la complexité via des décorateurs et s'intègre parfaitement au système d'injection de dépendances. > **Définition Rapide** > > Un WebSocket Gateway dans NestJS est une classe décorée avec `@WebSocketGateway()` qui gère la communication bidirectionnelle entre client et serveur. Il supporte plusieurs adaptateurs (Socket.IO, ws) et s'intègre aux Guards, Pipes et Interceptors de NestJS. ## Configuration d'un WebSocket Gateway avec Socket.IO L'adaptateur par défaut dans NestJS utilise [Socket.IO](https://socket.io/docs/v4/), qui fournit la reconnexion automatique, le support des rooms et le fallback vers le long-polling HTTP. L'installation nécessite le package spécifique à la plateforme en plus du module WebSockets principal. ```bash # terminal npm install @nestjs/websockets @nestjs/platform-socket.io socket.io ``` Un gateway basique écoute les messages entrants et peut diffuser des réponses aux clients connectés. ```typescript // chat.gateway.ts import { WebSocketGateway, WebSocketServer, SubscribeMessage, MessageBody, ConnectedSocket, } from '@nestjs/websockets'; import { Server, Socket } from 'socket.io'; @WebSocketGateway({ cors: { origin: '*' }, // Configure CORS pour les clients navigateur }) export class ChatGateway { @WebSocketServer() server: Server; // Accès au serveur Socket.IO sous-jacent @SubscribeMessage('message') // Écoute les événements 'message' handleMessage( @MessageBody() data: { text: string; room: string }, @ConnectedSocket() client: Socket, ): void { // Diffuse à tous les clients dans la room sauf l'expéditeur client.to(data.room).emit('message', { text: data.text, senderId: client.id, timestamp: Date.now(), }); } } ``` Le décorateur `@SubscribeMessage` lie une méthode à un nom d'événement spécifique. `@MessageBody()` extrait le payload, tandis que `@ConnectedSocket()` fournit l'accès au socket client pour des réponses ciblées. ## Hooks de Cycle de Vie pour la Gestion des Connexions Les gateways NestJS implémentent des interfaces de cycle de vie pour gérer les connexions et déconnexions des clients. Ces hooks permettent le nettoyage des ressources, le suivi de présence et la validation des connexions. ```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 { // Appelé une fois lors de l'initialisation du gateway this.logger.log('WebSocket Gateway initialisé'); } handleConnection(client: Socket): void { // Suivre les nouvelles connexions this.connectedUsers.set(client.id, { joinedAt: new Date() }); this.logger.log(`Client connecté: ${client.id}`); } handleDisconnect(client: Socket): void { // Nettoyage lors de la déconnexion this.connectedUsers.delete(client.id); this.logger.log(`Client déconnecté: ${client.id}`); } } ``` Les trois interfaces de cycle de vie servent des objectifs distincts : `OnGatewayInit` s'exécute une fois au démarrage, `OnGatewayConnection` se déclenche à chaque connexion client, et `OnGatewayDisconnect` gère le nettoyage quand les clients partent. ## Authentification avec les Guards WebSocket Les connexions WebSocket nécessitent une validation d'authentification avant d'autoriser l'accès aux événements protégés. Les Guards NestJS fonctionnent avec les gateways, bien que le contexte d'exécution diffère des requêtes HTTP. La [documentation officielle NestJS WebSockets](https://docs.nestjs.com/websockets/gateways) couvre l'intégration des guards en détail. ```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(); // Extraire le token depuis handshake auth ou query params const token = client.handshake.auth?.token || client.handshake.query?.token; if (!token) { throw new WsException('Token d\'authentification manquant'); } try { const payload = this.jwtService.verify(token as string); // Attacher les données utilisateur au socket pour utilisation ultérieure client.data.user = payload; return true; } catch { throw new WsException('Token invalide'); } } } ``` Le guard s'applique à la classe gateway ou aux gestionnaires de messages individuels via le décorateur `@UseGuards()`. La classe `WsException` lance des erreurs que le client reçoit via l'événement 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) // Protège tous les handlers dans ce gateway export class SecureChatGateway { @SubscribeMessage('privateMessage') handlePrivateMessage(): void { // Seuls les clients authentifiés atteignent ce handler } } ``` Pour les questions d'authentification au niveau module, consultez le [module d'entretien NestJS sur l'authentification et JWT](/technologies/node-nestjs/interview-questions/authentication-jwt) couvrant les stratégies JWT et la gestion des sessions. ## Patterns de Diffusion Basés sur les Rooms Les rooms Socket.IO permettent la livraison ciblée de messages vers des sous-ensembles de clients connectés. Les cas d'usage courants incluent les salons de chat, les lobbies de jeux et les fonctionnalités de collaboration en direct. ```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 } { // Ajouter le client à la room spécifiée client.join(roomId); // Notifier les autres dans 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 { // Envoyer à tous les clients dans la room, y compris l'expéditeur this.server.to(payload.roomId).emit('roomMessage', payload.message); } } ``` La distinction entre `client.to(room).emit()` et `server.to(room).emit()` est importante : le premier exclut l'expéditeur, tandis que le second inclut tous les membres de la room. ## Gestion des Erreurs avec les Filtres d'Exception Les exceptions WebSocket nécessitent des filtres dédiés car les filtres d'exception HTTP ne s'appliquent pas aux contextes gateway. Les filtres personnalisés capturent `WsException` et formatent les réponses d'erreur pour les 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(); // Envoyer une erreur structurée au client client.emit('error', { type: 'WsException', message: typeof error === 'string' ? error : error, timestamp: new Date().toISOString(), }); } } ``` Les filtres s'appliquent au niveau du gateway pour une gestion cohérente des erreurs sur tous les gestionnaires de messages. ```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 { // Tous les handlers bénéficient d'une gestion centralisée des erreurs } ``` Ce pattern reflète la philosophie NestJS des décorateurs et filtres décrite dans le [module middleware et intercepteurs](/technologies/node-nestjs/interview-questions/middleware-interceptors). ## Mise à l'Échelle des WebSockets avec l'Adaptateur Redis Les déploiements WebSocket mono-serveur échouent lorsque le load balancing distribue les clients sur plusieurs instances. L'[adaptateur Redis Socket.IO](https://socket.io/docs/v4/redis-adapter/) synchronise les événements entre les instances via un mécanisme 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 {} ``` Le gateway utilise ensuite l'adaptateur pour la communication inter-instances. ```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 { // Attacher l'adaptateur Redis pour le support multi-instances this.server.adapter(this.redisAdapter as any); } } ``` Avec l'adaptateur Redis, un message émis sur une instance serveur atteint les clients connectés à n'importe quelle instance du cluster. ## Questions d'Entretien Courantes sur les WebSockets NestJS Les entretiens techniques sondent souvent la compréhension des décisions d'architecture temps réel et des détails d'implémentation spécifiques à NestJS. > **Fréquemment Demandé** > > **Comment NestJS gère-t-il l'authentification WebSocket différemment de HTTP ?** > > Les middlewares HTTP ne s'exécutent pas pour les connexions WebSocket. L'authentification se produit pendant la phase de handshake ou via des Guards appliqués au gateway. La validation du token se fait généralement dans `handleConnection()` ou un Guard personnalisé qui lit depuis `socket.handshake.auth`. **Quelle est la différence entre la configuration du port `@WebSocketGateway()` et le port principal de l'application ?** Par défaut, les gateways WebSocket partagent le port du serveur HTTP. Spécifier un port dans `@WebSocketGateway(3001)` crée un serveur WebSocket séparé sur ce port. Les ports partagés simplifient le déploiement mais nécessitent un routage basé sur le chemin (`/socket.io`) lors de l'utilisation de reverse proxies. **Comment tester les gateways WebSocket dans NestJS ?** Les utilitaires de test NestJS supportent le test des gateways via `Test.createTestingModule()`. La bibliothèque [socket.io-client](https://github.com/socketio/socket.io-client) se connecte au serveur de test. Les hooks de cycle de vie et les gestionnaires de messages sont testés en émettant des événements et en vérifiant les réponses ou les effets de bord. ```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('reçoit un accusé de réception de message', (done) => { client.emit('message', { text: 'test', room: 'lobby' }); client.on('message', (data) => { expect(data.text).toBe('test'); done(); }); }); }); ``` **Quand utiliser l'adaptateur ws au lieu de Socket.IO ?** L'adaptateur [bibliothèque ws](https://github.com/websockets/ws) (`@nestjs/platform-ws`) offre une surcharge moindre pour les applications qui n'ont pas besoin des fonctionnalités Socket.IO comme la reconnexion automatique, les rooms ou les transports de fallback. Les systèmes de trading haute fréquence et les serveurs de jeux préfèrent souvent ws pour une latence réduite. Pour les concepts d'architecture NestJS plus larges, l'article connexe sur [Guards, Intercepteurs et Architecture Modulaire](/blog/node-nestjs/nestjs-guards-interceptors-modular-architecture) couvre comment ces patterns s'intègrent à travers les contextes HTTP et WebSocket. ## Conclusion - Les WebSocket Gateways s'intègrent à l'injection de dépendances, aux Guards et aux Filters de NestJS pour des patterns cohérents entre HTTP et endpoints temps réel - Les hooks de cycle de vie (`OnGatewayConnection`, `OnGatewayDisconnect`) gèrent le suivi de présence et le nettoyage des ressources - Les flux d'authentification diffèrent de HTTP ; la validation du token se produit pendant le handshake ou via des Guards WebSocket dédiés - La diffusion basée sur les rooms avec Socket.IO permet un messaging ciblé sans gérer manuellement les listes de sockets - L'adaptateur Redis résout la mise à l'échelle horizontale en synchronisant les événements entre plusieurs instances serveur - Les filtres d'exception nécessitent des implémentations spécifiques aux WebSocket utilisant `WsException` et des filtres personnalisés --- Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack. HTML version of this page: https://sharpskill.dev/fr/blog/node-nestjs/nestjs-websockets-real-time-gateway-best-practices