# NestJS e WebSocket nel 2026: Comunicazione Real-Time, Gateway e Domande da Colloquio > Padroneggiare i WebSocket in NestJS con pattern Gateway, integrazione Socket.IO, autenticazione, gestione errori e domande frequenti nei colloqui tecnici 2026. - Published: 2026-08-10 - Updated: 2026-08-10 - Author: Anthony Fillion-Maillet - Reading time: 5 min --- I WebSocket di NestJS offrono un approccio strutturato alla comunicazione real-time utilizzando il pattern Gateway. A differenza delle implementazioni WebSocket pure, NestJS astrae la complessità attraverso i decorator e si integra perfettamente con il sistema di dependency injection. > **Definizione Rapida** > > Un WebSocket Gateway in NestJS è una classe decorata con `@WebSocketGateway()` che gestisce la comunicazione bidirezionale tra client e server. Supporta molteplici adapter (Socket.IO, ws) e si integra con Guard, Pipe e Interceptor di NestJS. ## Configurazione di un WebSocket Gateway con Socket.IO L'adapter predefinito in NestJS utilizza [Socket.IO](https://socket.io/docs/v4/), che fornisce riconnessione automatica, supporto per le room e fallback su HTTP long-polling. L'installazione richiede il pacchetto specifico della piattaforma insieme al modulo core WebSockets. ```bash # terminal npm install @nestjs/websockets @nestjs/platform-socket.io socket.io ``` Un gateway base ascolta i messaggi in arrivo e può trasmettere risposte ai client connessi. ```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(), }); } } ``` Il decorator `@SubscribeMessage` associa un metodo a un nome evento specifico. `@MessageBody()` estrae il payload, mentre `@ConnectedSocket()` fornisce accesso al socket del client per risposte mirate. ## Hook del Ciclo di Vita per la Gestione delle Connessioni I gateway NestJS implementano interfacce del ciclo di vita per gestire connessioni e disconnessioni dei client. Questi hook abilitano la pulizia delle risorse, il tracciamento della presenza e la validazione delle connessioni. ```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}`); } } ``` Le tre interfacce del ciclo di vita hanno scopi distinti: `OnGatewayInit` viene eseguito una volta all'avvio, `OnGatewayConnection` si attiva per ogni connessione client, e `OnGatewayDisconnect` gestisce la pulizia quando i client si disconnettono. ## Autenticazione con WebSocket Guard Le connessioni WebSocket richiedono la validazione dell'autenticazione prima di consentire l'accesso a eventi protetti. I Guard NestJS funzionano con i gateway, anche se il contesto di esecuzione differisce dalle richieste HTTP. La [documentazione ufficiale NestJS WebSockets](https://docs.nestjs.com/websockets/gateways) tratta l'integrazione dei guard in dettaglio. ```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'); } } } ``` Il guard viene applicato alla classe gateway o ai singoli handler dei messaggi usando il decorator `@UseGuards()`. La classe `WsException` lancia errori che il client riceve attraverso l'evento error di 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) // Protect all handlers in this gateway export class SecureChatGateway { @SubscribeMessage('privateMessage') handlePrivateMessage(): void { // Only authenticated clients reach this handler } } ``` Per domande sull'autenticazione a livello di modulo, il [modulo interview sull'autenticazione NestJS](/technologies/node-nestjs/interview-questions/authentication-jwt) copre strategie JWT e gestione delle sessioni. ## Pattern di Broadcasting Basato su Room Le room di Socket.IO abilitano la consegna mirata dei messaggi a sottoinsiemi di client connessi. I casi d'uso comuni includono chat room, lobby di gioco e funzionalità di collaborazione live. ```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); } } ``` La distinzione tra `client.to(room).emit()` e `server.to(room).emit()` è importante: il primo esclude il mittente, mentre il secondo include tutti i membri della room. ## Gestione degli Errori con Exception Filter Le eccezioni WebSocket richiedono filtri dedicati poiché i filtri delle eccezioni HTTP non si applicano ai contesti gateway. I filtri personalizzati catturano `WsException` e formattano le risposte di errore per i client. ```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(), }); } } ``` I filtri vengono applicati a livello di gateway per una gestione coerente degli errori su tutti gli handler dei messaggi. ```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 } ``` Questo pattern rispecchia la filosofia NestJS di decorator e filtri descritta nel [modulo middleware e interceptor](/technologies/node-nestjs/interview-questions/middleware-interceptors). ## Scalabilità dei WebSocket con Redis Adapter I deployment WebSocket su singolo server falliscono quando il load balancing distribuisce i client su più istanze. Il [Redis adapter di Socket.IO](https://socket.io/docs/v4/redis-adapter/) sincronizza gli eventi tra le istanze attraverso un meccanismo 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 {} ``` Il gateway utilizza quindi l'adapter per la comunicazione tra istanze. ```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); } } ``` Con il Redis adapter, un messaggio emesso su un'istanza server raggiunge i client connessi a qualsiasi istanza nel cluster. ## Domande Frequenti nei Colloqui su NestJS WebSocket I colloqui tecnici spesso indagano la comprensione delle decisioni architetturali real-time e dei dettagli implementativi specifici di NestJS. > **Domanda Frequente** > > **Come gestisce NestJS l'autenticazione WebSocket in modo diverso da HTTP?** > > Il middleware HTTP non viene eseguito per le connessioni WebSocket. L'autenticazione avviene durante la fase di handshake o attraverso Guard applicati al gateway. La validazione del token tipicamente avviene in `handleConnection()` o in un Guard personalizzato che legge da `socket.handshake.auth`. **Qual è la differenza tra la configurazione della porta di `@WebSocketGateway()` e la porta dell'applicazione principale?** Per impostazione predefinita, i WebSocket Gateway condividono la porta del server HTTP. Specificando una porta in `@WebSocketGateway(3001)` si crea un server WebSocket separato su quella porta. Le porte condivise semplificano il deployment ma richiedono routing basato sul path (`/socket.io`) quando si utilizzano reverse proxy. **Come si testano i WebSocket Gateway in NestJS?** Le utility di test NestJS supportano il test dei gateway attraverso `Test.createTestingModule()`. La libreria [socket.io-client](https://github.com/socketio/socket.io-client) si connette al server di test. Gli hook del ciclo di vita e gli handler dei messaggi vengono testati emettendo eventi e verificando le risposte o gli effetti collaterali. ```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(); }); }); }); ``` **Quando si dovrebbe usare l'adapter ws invece di Socket.IO?** L'adapter della [libreria ws](https://github.com/websockets/ws) (`@nestjs/platform-ws`) offre minor overhead per applicazioni che non necessitano delle funzionalità di Socket.IO come riconnessione automatica, room o trasporti fallback. I sistemi di trading ad alta frequenza e i server di gioco spesso preferiscono ws per la latenza ridotta. Per concetti architetturali NestJS più ampi, l'articolo correlato su [Guard, Interceptor e Architettura Modulare](/blog/node-nestjs/nestjs-guards-interceptors-modular-architecture) copre come questi pattern si integrano attraverso i contesti HTTP e WebSocket. ## Conclusione - I WebSocket Gateway si integrano con dependency injection, Guard e Filter di NestJS per pattern coerenti tra endpoint HTTP e real-time - Gli hook del ciclo di vita (`OnGatewayConnection`, `OnGatewayDisconnect`) gestiscono il tracciamento della presenza e la pulizia delle risorse - I flussi di autenticazione differiscono da HTTP; la validazione del token avviene durante l'handshake o attraverso Guard WebSocket dedicati - Il broadcasting basato su room con Socket.IO abilita la messaggistica mirata senza gestire manualmente le liste di socket - Il Redis adapter risolve la scalabilità orizzontale sincronizzando gli eventi tra più istanze server - I filtri delle eccezioni richiedono implementazioni specifiche per WebSocket usando `WsException` e filtri personalizzati --- Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack. HTML version of this page: https://sharpskill.dev/it/blog/node-nestjs/nestjs-websockets-real-time-gateway-best-practices