NestJS und WebSockets 2026: Echtzeit-Kommunikation, Gateways und Interview-Fragen
WebSockets in NestJS meistern mit Gateway-Mustern, Socket.IO-Integration, Authentifizierung, Fehlerbehandlung und häufigen Interview-Fragen für 2026.

NestJS WebSockets bieten einen strukturierten Ansatz für Echtzeit-Kommunikation mittels des Gateway-Musters. Im Gegensatz zu rohen WebSocket-Implementierungen abstrahiert NestJS die Komplexität durch Decorators und integriert sich nahtlos in das Dependency-Injection-System.
Ein WebSocket Gateway in NestJS ist eine Klasse, die mit @WebSocketGateway() dekoriert wird und bidirektionale Kommunikation zwischen Client und Server ermöglicht. Es unterstützt mehrere Adapter (Socket.IO, ws) und integriert sich mit NestJS Guards, Pipes und Interceptors.
Einrichten eines WebSocket Gateways mit Socket.IO
Der Standard-Adapter in NestJS verwendet Socket.IO, das automatische Wiederverbindung, Room-Unterstützung und Fallback zu HTTP Long-Polling bietet. Die Installation erfordert das plattformspezifische Paket zusammen mit dem Core-WebSockets-Modul.
# terminal
npm install @nestjs/websockets @nestjs/platform-socket.io socket.ioEin einfaches Gateway lauscht auf eingehende Nachrichten und kann Antworten an verbundene Clients broadcasten.
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(),
});
}
}Der @SubscribeMessage-Decorator bindet eine Methode an einen spezifischen Event-Namen. @MessageBody() extrahiert den Payload, während @ConnectedSocket() Zugriff auf den Client-Socket für gezielte Antworten bietet.
Lifecycle Hooks für Verbindungsmanagement
NestJS Gateways implementieren Lifecycle-Interfaces für die Behandlung von Client-Verbindungen und -Trennungen. Diese Hooks ermöglichen Ressourcenbereinigung, Präsenzverfolgung und Verbindungsvalidierung.
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 {
// 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}`);
}
}Die drei Lifecycle-Interfaces dienen unterschiedlichen Zwecken: OnGatewayInit läuft einmal beim Start, OnGatewayConnection wird pro Client-Verbindung ausgelöst, und OnGatewayDisconnect behandelt die Bereinigung beim Verlassen von Clients.
Authentifizierung mit WebSocket Guards
WebSocket-Verbindungen erfordern Authentifizierungsvalidierung bevor Zugriff auf geschützte Events gewährt wird. NestJS Guards funktionieren mit Gateways, obwohl sich der Ausführungskontext von HTTP-Anfragen unterscheidet. Die offizielle NestJS WebSockets-Dokumentation behandelt die Guard-Integration im Detail.
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');
}
}
}Der Guard wird auf die Gateway-Klasse oder einzelne Message-Handler mit dem @UseGuards()-Decorator angewendet. Die WsException-Klasse wirft Fehler, die der Client über das Socket.IO Error-Event empfängt.
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
}
}Für Fragen zur Modul-Level-Authentifizierung bietet das NestJS Authentifizierungs-Interview-Modul Informationen zu JWT-Strategien und Session-Management.
Bereit für deine Node.js / NestJS-Interviews?
Übe mit unseren interaktiven Simulatoren, Flashcards und technischen Tests.
Room-basierte Broadcasting-Muster
Socket.IO Rooms ermöglichen gezielte Nachrichtenzustellung an Teilmengen verbundener Clients. Häufige Anwendungsfälle umfassen Chat-Räume, Spiel-Lobbys und Live-Kollaborationsfunktionen.
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);
}
}Der Unterschied zwischen client.to(room).emit() und server.to(room).emit() ist wichtig: Ersteres schließt den Sender aus, während Letzteres alle Room-Mitglieder einschließt.
Fehlerbehandlung mit Exception Filters
WebSocket-Exceptions erfordern dedizierte Filter, da HTTP Exception Filters nicht auf Gateway-Kontexte anwendbar sind. Benutzerdefinierte Filter fangen WsException ab und formatieren Fehlerantworten für Clients.
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(),
});
}
}Filter werden auf Gateway-Ebene angewendet für konsistente Fehlerbehandlung über alle Message-Handler hinweg.
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
}Dieses Muster spiegelt die NestJS-Philosophie von Decorators und Filtern wider, die im Middleware und Interceptors Modul beschrieben wird.
Skalierung von WebSockets mit Redis Adapter
Einzelserver-WebSocket-Deployments versagen, wenn Load Balancing Clients über mehrere Instanzen verteilt. Der Socket.IO Redis-Adapter synchronisiert Events über Instanzen hinweg durch einen Pub/Sub-Mechanismus.
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 {}Das Gateway verwendet dann den Adapter für instanzübergreifende Kommunikation.
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);
}
}Mit dem Redis-Adapter erreicht eine Nachricht, die auf einer Server-Instanz emittiert wird, Clients, die mit jeder Instanz im Cluster verbunden sind.
Häufige Interview-Fragen zu NestJS WebSockets
Technische Interviews prüfen oft das Verständnis von Echtzeit-Architekturentscheidungen und NestJS-spezifischen Implementierungsdetails.
Wie behandelt NestJS WebSocket-Authentifizierung anders als HTTP?
HTTP-Middleware wird für WebSocket-Verbindungen nicht ausgeführt. Authentifizierung erfolgt während der Handshake-Phase oder durch Guards, die auf das Gateway angewendet werden. Token-Validierung geschieht typischerweise in handleConnection() oder einem benutzerdefinierten Guard, der aus socket.handshake.auth liest.
Was ist der Unterschied zwischen @WebSocketGateway() Port-Konfiguration und dem Hauptanwendungsport?
Standardmäßig teilen sich WebSocket Gateways den HTTP-Server-Port. Die Angabe eines Ports in @WebSocketGateway(3001) erstellt einen separaten WebSocket-Server auf diesem Port. Geteilte Ports vereinfachen das Deployment, erfordern aber pfadbasiertes Routing (/socket.io) bei Verwendung von Reverse Proxies.
Wie testet man WebSocket Gateways in NestJS?
NestJS Test-Utilities unterstützen Gateway-Tests durch Test.createTestingModule(). Die socket.io-client-Bibliothek verbindet sich mit dem Testserver. Lifecycle-Hooks und Message-Handler werden getestet, indem Events emittiert und Antworten oder Seiteneffekte überprüft werden.
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();
});
});
});Wann sollte der ws-Adapter anstelle von Socket.IO verwendet werden?
Der ws-Bibliothek-Adapter (@nestjs/platform-ws) bietet geringeren Overhead für Anwendungen, die Socket.IO-Features wie automatische Wiederverbindung, Rooms oder Fallback-Transporte nicht benötigen. Hochfrequenz-Handelssysteme und Spieleserver bevorzugen oft ws für reduzierte Latenz.
Für breitere NestJS-Architekturkonzepte behandelt der verwandte Artikel zu Guards, Interceptors und Modulare Architektur, wie diese Muster über HTTP- und WebSocket-Kontexte hinweg integriert werden.
Fazit
- WebSocket Gateways integrieren sich mit NestJS Dependency Injection, Guards und Filtern für konsistente Muster über HTTP- und Echtzeit-Endpunkte hinweg
- Lifecycle Hooks (
OnGatewayConnection,OnGatewayDisconnect) verwalten Präsenzverfolgung und Ressourcenbereinigung - Authentifizierungsabläufe unterscheiden sich von HTTP; Token-Validierung erfolgt während des Handshakes oder durch dedizierte WebSocket Guards
- Room-basiertes Broadcasting mit Socket.IO ermöglicht gezielte Nachrichtenübermittlung ohne manuelle Verwaltung von Socket-Listen
- Redis-Adapter löst horizontale Skalierung durch Synchronisierung von Events über mehrere Server-Instanzen
- Exception Filter erfordern WebSocket-spezifische Implementierungen mit
WsExceptionund benutzerdefinierten Filtern
Fang an zu üben!
Teste dein Wissen mit unseren Interview-Simulatoren und technischen Tests.

Geschrieben von
Anthony Fillion-MailletFullstack-Entwickler, Gründer von SharpSkill
Seit über 10 Jahren Fullstack-Entwickler. Er leitet SharpSkill und verantwortet alles, was hier erscheint.
Aktualisiert am 10. August 2026
Teilen
Verwandte Artikel

NestJS und GraphQL 2026: Schemas, Resolver und Interviewfragen
Die Integration von NestJS mit GraphQL ermöglicht die Entwicklung typsicherer APIs. Dieses Tutorial behandelt Code-First und Schema-First Ansätze, Resolver-Muster und Interviewfragen für 2026.

NestJS und TypeORM 2026: Migrationen, Relationen und Interviewfragen
NestJS und TypeORM gehören 2026 zu den etabliertesten Kombinationen im Node.js-Backend-Bereich. Dieser Artikel behandelt Migrationen, Relationen, Transaktionen und Interviewfragen.

Node.js 24 im Jahr 2026: URLPattern, Permission Model und Interviewfragen
Node.js 24 LTS bringt ein stabiles Permission Model, globale URLPattern-API, explizites Ressourcenmanagement mit using/await using und V8 13.6. Ein detaillierter Einblick in die Funktionen, die für Produktion und Vorstellungsgespräche relevant sind.