### Complete UwsAdapter Configuration Example Source: https://uwest.js.org/docs/uwsadapter A full example showing server configuration, performance tuning, CORS, and dependency injection. It also registers a gateway and starts the HTTP server. ```typescript import { NestFactory } from '@nestjs/core'; import { ModuleRef } from '@nestjs/core'; import { UwsAdapter, SHARED_COMPRESSOR } from 'uwestjs'; const app = await NestFactory.create(AppModule); const moduleRef = app.get(ModuleRef); const adapter = new UwsAdapter(app, { // Server configuration port: 8099, path: '/ws', // Performance tuning maxPayloadLength: 1024 * 1024, // 1MB idleTimeout: 300, // 5 minutes compression: SHARED_COMPRESSOR, // CORS configuration cors: { origin: (origin) => origin?.endsWith('.example.com') ?? false, credentials: true, methods: ['GET', 'POST'], allowedHeaders: ['Content-Type', 'Authorization'], maxAge: 3600, }, // Enable DI for guards/pipes/filters (auto-wrapped) moduleRef, }); app.useWebSocketAdapter(adapter); // Register gateways const gateway = app.get(EventsGateway); adapter.registerGateway(gateway); await app.listen(3000); ``` -------------------------------- ### Example of registerGateway usage Source: https://uwest.js.org/docs/uwsadapter Shows how to create a NestJS app, instantiate UwsAdapter, register a gateway manually, and start the server. ```typescript const app = await NestFactory.create(AppModule); const adapter = new UwsAdapter(app, { port: 8099 }); app.useWebSocketAdapter(adapter); // Manually register your gateway const chatGateway = app.get(ChatGateway); adapter.registerGateway(chatGateway); await app.listen(3000); ``` -------------------------------- ### Common Configurations Source: https://uwest.js.org/docs/multipart Examples of common configuration setups for the multipart handler, including strict limits, generous limits, and single file upload. ```APIDOC ## Common Configurations ### Strict Limits (Recommended for Production) ```typescript await req.multipart( { limits: { fieldNameSize: 100, // 100 bytes fieldSize: 1024 * 1024, // 1MB fields: 20, // 20 fields max fileSize: 50 * 1024 * 1024, // 50MB per file files: 10, // 10 files max parts: 30, // 30 parts total }, }, handler ); ``` ### Generous Limits (Development) ```typescript await req.multipart( { limits: { fileSize: 100 * 1024 * 1024, // 100MB per file files: 50, // 50 files max }, }, handler ); ``` ### Single File Upload ```typescript await req.multipart( { limits: { files: 1, // Only 1 file allowed fileSize: 10 * 1024 * 1024, // 10MB max }, }, handler ); ``` ``` -------------------------------- ### Basic UwsAdapter Setup with NestJS Source: https://uwest.js.org/docs/uwsadapter Use this to create a basic WebSocket adapter with uwestjs. It sets the port to 8099, registers a gateway, and starts the HTTP server on port 3000. ```typescript import { NestFactory } from '@nestjs/core'; import { UwsAdapter } from 'uwestjs'; const app = await NestFactory.create(AppModule); const adapter = new UwsAdapter(app, { port: 8099 }); app.useWebSocketAdapter(adapter); const gateway = app.get(EventsGateway); adapter.registerGateway(gateway); await app.listen(3000); ``` -------------------------------- ### handleConnection() advanced example Source: https://uwest.js.org/docs/lifecycle Advanced handleConnection example that sends a welcome message, auto-joins the lobby, tracks the connection, and notifies other users. ```typescript @WebSocketGateway() export class ChatGateway implements OnGatewayConnection { private connectedUsers = new Map(); handleConnection(client: UwsSocket) { console.log(`Client connected: ${client.id}`); // Send welcome message client.emit('welcome', { message: 'Welcome to the chat!', serverId: 'server-1', timestamp: Date.now(), }); // Auto-join lobby client.join('lobby'); // Track connection this.connectedUsers.set(client.id, { connectedAt: Date.now(), lastActivity: Date.now(), }); // Notify others client.to('lobby').emit('user-connected', { userId: client.id, count: this.connectedUsers.size, }); } } ``` -------------------------------- ### Advanced Static File Examples Source: https://uwest.js.org/docs/http-server Examples demonstrating multiple static directories, long-term caching, custom index files, and disabling caching for development. ```APIDOC ## Advanced Static File Examples ### Multiple Static Directories ```typescript // Serve from multiple directories app.useStaticAssets('public', { prefix: '/public' }); app.useStaticAssets('uploads', { prefix: '/uploads' }); app.useStaticAssets('assets', { prefix: '/assets' }); ``` ### Long-term Caching ```typescript // Cache static assets for 1 year app.useStaticAssets('public/assets', { prefix: '/assets', maxAge: '1y', // or milliseconds: 31536000000 immutable: true, // Add immutable directive }); ``` ### Custom Index Files ```typescript app.useStaticAssets('docs', { prefix: '/docs', index: ['README.md', 'index.html', 'index.htm'], }); ``` ### Disable Caching for Development ```typescript if (process.env.NODE_ENV === 'development') { app.useStaticAssets('public', { maxAge: 0, etag: false, cacheControl: false, }); } ``` ``` -------------------------------- ### afterInit() advanced example with cleanup Source: https://uwest.js.org/docs/lifecycle Advanced afterInit example that loads active games and sets up a cleanup interval. Also implements OnModuleDestroy to clear the interval and prevent resource leaks. ```typescript import { OnModuleDestroy } from '@nestjs/common'; import { WebSocketGateway, OnGatewayInit } from '@nestjs/websockets'; @WebSocketGateway() export class GameGateway implements OnGatewayInit, OnModuleDestroy { private games = new Map(); private cleanupInterval?: NodeJS.Timeout; afterInit(server: any) { console.log('Game gateway initialized'); // Load active games from database this.loadActiveGames(); // Start cleanup timer this.cleanupInterval = setInterval(() => { this.cleanupInactiveGames(); }, 60000); // Every minute } onModuleDestroy() { // Clean up interval timer to prevent resource leak if (this.cleanupInterval) { clearInterval(this.cleanupInterval); this.cleanupInterval = undefined; } } private async loadActiveGames() { const games = await this.gameService.findActive(); games.forEach(game => { this.games.set(game.id, game); }); console.log(`Loaded ${games.length} active games`); } private cleanupInactiveGames() { // Cleanup logic } } ``` -------------------------------- ### join() usage example Source: https://uwest.js.org/docs/uwssocket Example of joining a single room, multiple rooms, and joining a room based on user data within a message handler. ```typescript // Join single room client.join('lobby'); // Join multiple rooms client.join(['game-1', 'chat-general']); // Join room based on user data @SubscribeMessage('join-game') handleJoinGame( @MessageBody() gameId: string, @ConnectedSocket() client: UwsSocket, ) { client.join(`game:${gameId}`); client.to(`game:${gameId}`).emit('player-joined', { playerId: client.id, username: client.data?.user?.name, }); } ``` -------------------------------- ### handleDisconnect() advanced example Source: https://uwest.js.org/docs/lifecycle Advanced handleDisconnect example that notifies the game room, handles player leave, cleans up tracking, and saves session data. ```typescript @WebSocketGateway() export class GameGateway implements OnGatewayDisconnect { handleDisconnect(client: UwsSocket) { console.log(`Client disconnected: ${client.id}`); // Get user data before cleanup const gameId = client.data?.gameId; const username = client.data?.user?.name; // Notify game room if user was in a game if (gameId) { client.to(`game:${gameId}`).emit('player-disconnected', { playerId: client.id, username, }); // Handle game state this.handlePlayerLeave(gameId, client.id); } // Clean up tracking this.connectedUsers.delete(client.id); // Save session data if (client.data?.user) { this.saveUserSession(client.data.user.id, { disconnectedAt: Date.now(), lastGameId: gameId, }); } } } ``` -------------------------------- ### origin configuration examples Source: https://uwest.js.org/docs/uwsadapter Examples showing how to set the origin option for different scenarios: specific origin, wildcard, multiple origins, and dynamic validation. Note: Never use origin: '*' with credentials: true in production. ```typescript // Specific origin (recommended for production) cors: { origin: 'https://example.com' } // Allow all origins (use only for development/testing) cors: { origin: '*' } // Allow multiple origins cors: { origin: ['https://example.com', 'https://app.example.com'] } // Dynamic validation (recommended for flexible security) cors: { origin: (origin) => { // Allow all subdomains of example.com return origin?.endsWith('.example.com') ?? false; } } ``` -------------------------------- ### to() usage example Source: https://uwest.js.org/docs/uwssocket Example of emitting to single and multiple rooms excluding the sender, chaining, and a game example broadcasting moves to all players except the sender. ```typescript // Send to single room, excluding sender client.to('room1').emit('message', data); // Send to multiple rooms, excluding sender client.to(['room1', 'room2']).emit('message', data); // Chaining client.to('room1').to('room2').emit('message', data); // Game example @SubscribeMessage('game-move') handleMove( @MessageBody() move: any, @ConnectedSocket() client: UwsSocket, ) { const gameId = client.data?.gameId; // Broadcast move to all players in the game except the sender client.to(`game:${gameId}`).emit('move-made', { playerId: client.id, move, }); } ``` -------------------------------- ### Accept-Encoding header example Source: https://uwest.js.org/docs/http-compression Shows an example Accept-Encoding header that a client might send, indicating support for gzip, deflate, and brotli. The server uses this header to select the best compression algorithm. ```http Accept-Encoding: gzip, deflate, br ``` -------------------------------- ### type() usage example Source: https://uwest.js.org/docs/http-response Example of setting Content-Type using MIME types, file extensions, and leading dot extensions. ```typescript @Get() handler(@Res() res: UwsResponse) { // MIME type res.type('application/json').send('{}'); // File extension res.type('json').send('{}'); res.type('html').send('

Hello

'); res.type('txt').send('Plain text'); res.type('png').send(imageBuffer); // With leading dot res.type('.pdf').send(pdfBuffer); } ``` -------------------------------- ### Content Negotiation example Source: https://uwest.js.org/docs/http-response Example of content negotiation based on the Accept header. It supports json, xml, and csv, returning 406 with supported types if none match. ```typescript @Get('data') async getData(@Req() req: UwsRequest, @Res() res: UwsResponse) { const data = await this.dataService.getData(); const accept = req.accepts('json', 'xml', 'csv'); switch (accept) { case 'json': return res.json(data); case 'xml': const xml = this.convertToXML(data); return res.type('xml').send(xml); case 'csv': const csv = this.convertToCSV(data); return res.type('csv') .attachment('data.csv') .send(csv); default: return res.status(406).json({ error: 'Not Acceptable', supported: ['application/json', 'application/xml', 'text/csv'], }); } } ``` -------------------------------- ### Vary header example Source: https://uwest.js.org/docs/http-compression Example HTTP response showing the Content-Encoding and Vary headers added to compressed responses for proper caching. ```http HTTP/1.1 200 OK Content-Encoding: gzip Vary: Accept-Encoding Content-Type: application/json ``` -------------------------------- ### Path Traversal Protection - Example Requests Source: https://uwest.js.org/docs/static-files Shows example HTTP requests that are blocked by the server's path traversal protection, returning 404 Not Found. ```text GET /../../../etc/passwd → 404 Not Found GET /./secret.txt → 404 Not Found GET /%2e%2e/secret.txt → 404 Not Found ``` -------------------------------- ### Install uWestJS with pnpm Source: https://uwest.js.org/docs/Middleware.md Install uWestJS using pnpm. Requires Node.js 20, 22, 24, or 25, NestJS >= 11.0.0, and TypeScript >= 6.0.0. ```bash pnpm add uwestjs ``` -------------------------------- ### BroadcastOperator emit() method examples Source: https://uwest.js.org/docs/broadcast-operator Examples of using emit() to broadcast to all clients, to a specific room, to a room excluding specific clients, and complex targeting with multiple rooms and exclusions. ```typescript // Broadcast to all clients client.broadcast.emit('announcement', { message: 'Server restart in 5 min' }); // Broadcast to specific room client.broadcast.to('game-1').emit('game-update', { status: 'started' }); // Broadcast to room, excluding specific clients client.broadcast .to('chat') .except(['client-1', 'client-2']) .emit('message', { text: 'Hello!' }); // Complex targeting client.broadcast .to(['room1', 'room2']) .except('client-1') .emit('notification', { type: 'info' }); ``` -------------------------------- ### BroadcastOperator to() method examples Source: https://uwest.js.org/docs/broadcast-operator Examples of using to() to target single or multiple rooms, chaining to() calls, and using an empty array to broadcast to zero rooms. ```typescript // Target single room client.broadcast.to('room1').emit('message', data); // Target multiple rooms client.broadcast.to(['room1', 'room2']).emit('message', data); // Chaining multiple to() calls client.broadcast.to('room1').to('room2').emit('message', data); // Empty array = broadcast to zero rooms (no clients) client.broadcast.to([]).emit('message', data); ``` -------------------------------- ### Install uWestJS with npm Source: https://uwest.js.org/docs/Middleware.md Install uWestJS using npm. Requires Node.js 20, 22, 24, or 25, NestJS >= 11.0.0, and TypeScript >= 6.0.0. ```bash npm install uwestjs ``` -------------------------------- ### bodyParser example Source: https://uwest.js.org/docs/http-server Configures automatic body parsing for different content types. This example enables raw buffer parsing and text parsing in addition to the defaults. ```typescript new UwsPlatformAdapter({ bodyParser: { json: true, urlencoded: true, raw: true, // Enable raw buffer parsing text: true, // Enable text parsing }, }) ``` -------------------------------- ### Automatic compression example in TypeScript Source: https://uwest.js.org/docs/http-compression Example controller that returns a large response, which will be automatically compressed if the client supports compression and the response size exceeds the threshold (default 1KB). ```typescript @Controller('api') export class ApiController { @Get('data') getData() { // Large response will be automatically compressed return { data: Array(1000).fill({ id: 1, name: 'Item', description: 'Description' }), }; } } ``` -------------------------------- ### Route Paths with Controller Prefix Source: https://uwest.js.org/docs/http-routing Routes are automatically prefixed with the controller path. The example shows how @Get decorators map to full paths like GET /api/v1/users and GET /api/v1/users/:id. ```typescript @Controller('api/v1/users') export class UsersController { @Get() // Matches: GET /api/v1/users findAll() { } @Get(':id') // Matches: GET /api/v1/users/:id findOne() { } @Get('profile/:id') // Matches: GET /api/v1/users/profile/:id getProfile() { } } ``` -------------------------------- ### afterInit() basic example Source: https://uwest.js.org/docs/lifecycle Basic implementation of the afterInit hook, called after the gateway is initialized. Logs initialization and provides comments for typical tasks. ```typescript import { OnGatewayInit } from '@nestjs/websockets'; @WebSocketGateway() export class ChatGateway implements OnGatewayInit { afterInit(server: any) { console.log('Gateway initialized'); // Perform initialization tasks // - Load initial data // - Set up timers // - Configure gateway state } } ``` -------------------------------- ### listen() Source: https://uwest.js.org/docs/http-server Starts the HTTP server on the specified port. Supports optional hostname and error-first callback. Must be called after app.init(). ```APIDOC ## [POST] /listen ### Description Starts the HTTP server on the specified port. Supports optional hostname and error-first callback. Must be called after app.init(). ### Method POST ### Endpoint /listen ### Parameters #### Path Parameters - **port** (number) - Required - Port number to listen on (0-65535) - **hostname** (string) - Optional - Hostname (default: '0.0.0.0') - **callback** (function) - Optional - Error-first callback when server starts or fails ### Request Example ```typescript const adapter = new UwsPlatformAdapter(); const app = await NestFactory.create(AppModule, adapter); await app.init(); // Simple adapter.listen(3000); // With error handling adapter.listen(3000, (error) => { if (error) { console.error('Failed to start server:', error); process.exit(1); } console.log('Server started on port 3000'); }); // With hostname and error handling adapter.listen(3000, '127.0.0.1', (error) => { if (error) { console.error('Failed to start server:', error); process.exit(1); } console.log('Server started on localhost:3000'); }); ``` ### Response #### Success Response (200) - **void** - No return value #### Response Example ``` No response body ``` ``` -------------------------------- ### JSON API Response example Source: https://uwest.js.org/docs/http-response Example of a GET endpoint returning a JSON response. It returns a 404 with an error object if the user is not found, otherwise returns the user data with a timestamp meta field. ```typescript @Get('users/:id') async getUser(@Param('id') id: string, @Res() res: UwsResponse) { const user = await this.userService.findById(id); if (!user) { return res.status(404).json({ error: 'User not found', statusCode: 404, }); } return res.json({ data: user, meta: { timestamp: Date.now() }, }); } ``` -------------------------------- ### Complete Configuration with app.useStaticAssets Source: https://uwest.js.org/docs/static-files Shows a full configuration example for serving static files from the 'public' directory with a '/static' prefix, custom index files, a one-year maxAge, strong ETags, and other options. Note the comments explaining string vs number formats for maxAge and the etag values. ```typescript app.useStaticAssets('public', { prefix: '/static', index: ['index.html', 'index.htm'], maxAge: '1y', // String format: 1 year (or use number in milliseconds: 31536000000) etag: 'strong', // 'weak' (default), 'strong', true, or false lastModified: true, cacheControl: true, immutable: true, dotfiles: 'ignore', redirect: true, silent: false, }); ``` -------------------------------- ### Conditional Response with ETag example Source: https://uwest.js.org/docs/http-response Example of conditional GET using ETag. It compares the If-None-Match header with a generated ETag; if they match, returns 304, otherwise sets ETag and Cache-Control headers and returns the resource. ```typescript @Get('resource') async getResource(@Req() req: UwsRequest, @Res() res: UwsResponse) { const resource = await this.resourceService.get(); const etag = this.generateETag(resource); const ifNoneMatch = req.get('If-None-Match'); if (ifNoneMatch === etag) { return res.status(304).send(); } res.setHeader('ETag', etag); res.setHeader('Cache-Control', 'public, max-age=3600'); res.json(resource); } ``` -------------------------------- ### Using listen() with error handling and hostname Source: https://uwest.js.org/docs/http-server Example showing how to initialize the adapter and call listen() with different options: simple port, error handling, and hostname with error handling. Requires calling app.init() before adapter.listen(). ```typescript const adapter = new UwsPlatformAdapter(); const app = await NestFactory.create(AppModule, adapter); await app.init(); // Simple adapter.listen(3000); // With error handling adapter.listen(3000, (error) => { if (error) { console.error('Failed to start server:', error); process.exit(1); } console.log('Server started on port 3000'); }); // With hostname and error handling adapter.listen(3000, '127.0.0.1', (error) => { if (error) { console.error('Failed to start server:', error); process.exit(1); } console.log('Server started on localhost:3000'); }); ``` -------------------------------- ### uWestJS server setup with UwsPlatformAdapter Source: https://uwest.js.org/docs/http-server After migrating to uWestJS, this server creates a UwsPlatformAdapter with maxBodySize and trustProxy options, calls app.init() before adapter.listen(), and logs a startup message. ```typescript import { NestFactory } from '@nestjs/core'; import { UwsPlatformAdapter } from 'uwestjs'; import { AppModule } from './app.module'; async function bootstrap() { const adapter = new UwsPlatformAdapter({ maxBodySize: 10 * 1024 * 1024, trustProxy: true, }); const app = await NestFactory.create(AppModule, adapter); app.enableCors(); app.useStaticAssets('public'); // Key difference: init() before listen() await app.init(); adapter.listen(3000, () => { console.log('Server running on port 3000'); }); } bootstrap(); ``` -------------------------------- ### Get route parameters Source: https://uwest.js.org/docs/http-request Shows how to access route parameters extracted from the URL path via the `params` property. Includes examples for single and multiple parameters. ```typescript params: Record ``` ```typescript @Get(':id') handler(@Req() req: UwsRequest, @Param('id') id: string) { console.log(req.params.id); // Same as id parameter } @Get('users/:userId/posts/:postId') handler(@Req() req: UwsRequest) { console.log(req.params.userId); // '123' console.log(req.params.postId); // '456' } ``` -------------------------------- ### Serve from multiple static directories Source: https://uwest.js.org/docs/http-server Example of serving static files from multiple directories with distinct URL prefixes. ```typescript // Serve from multiple directories app.useStaticAssets('public', { prefix: '/public' }); app.useStaticAssets('uploads', { prefix: '/uploads' }); app.useStaticAssets('assets', { prefix: '/assets' }); ``` -------------------------------- ### Share uWebSockets.js instance between HTTP and WebSocket Source: https://uwest.js.org/docs/uwsadapter Starting from v2.0.0, you can share a single uWebSockets.js instance between HTTP and WebSocket. This example creates a shared uWS instance, sets up both HTTP and WebSocket adapters, registers a gateway, and starts the server on port 3000. The HTTP adapter manages the listening port. ```typescript import { NestFactory } from '@nestjs/core'; import { UwsPlatformAdapter, UwsAdapter, App } from 'uwestjs'; // Create shared uWS instance const uwsApp = App(); // HTTP adapter const httpAdapter = new UwsPlatformAdapter(uwsApp); const app = await NestFactory.create(AppModule, httpAdapter); // WebSocket adapter (shares the same uWS instance) const wsAdapter = new UwsAdapter(app, { uwsApp }); app.useWebSocketAdapter(wsAdapter); // Register gateways const gateway = app.get(EventsGateway); wsAdapter.registerGateway(gateway); // Start server (HTTP adapter manages the listening port) await app.listen(3000); ``` -------------------------------- ### Separate Ports for HTTP and WebSocket Source: https://uwest.js.org/docs/http-server Use this setup when you need HTTP and WebSocket servers to listen on different ports. It creates a UwsPlatformAdapter for HTTP on port 3000 and a UwsAdapter for WebSocket on port 8099, then initializes the NestJS application and starts the HTTP server. ```typescript import { NestFactory } from '@nestjs/core'; import { UwsPlatformAdapter } from 'uwestjs'; import { UwsAdapter } from 'uwestjs/websocket'; import { AppModule } from './app.module'; async function bootstrap() { // HTTP on port 3000 const httpAdapter = new UwsPlatformAdapter(); const app = await NestFactory.create(AppModule, httpAdapter); // WebSocket on port 8099 const wsAdapter = new UwsAdapter(app, { port: 8099 }); app.useWebSocketAdapter(wsAdapter); // Initialize the app await app.init(); // Start HTTP server httpAdapter.listen(3000, () => { console.log('HTTP server running on port 3000'); console.log('WebSocket server running on port 8099'); }); } bootstrap(); ``` -------------------------------- ### Get request header with get() Source: https://uwest.js.org/docs/http-request Shows how to get a request header value case-insensitively using the get() method. Returns header value or undefined. ```typescript get(name: string): string | string[] | undefined ``` ```typescript @Get() handler(@Req() req: UwsRequest) { const contentType = req.get('Content-Type'); const auth = req.get('Authorization'); const customHeader = req.get('X-Custom-Header'); } ``` -------------------------------- ### Complete Gateway Example with Lifecycle Hooks and Message Handling Source: https://uwest.js.org/docs/ws-decorators Shows a full ChatGateway implementing OnGatewayInit, OnGatewayConnection, and OnGatewayDisconnect. It uses @UseFilters(WsExceptionFilter) at class level, joins clients to a 'lobby' room on connection, and handles 'message' and 'secure-action' events with validation and guards. ```typescript import { WebSocketGateway, SubscribeMessage, MessageBody, ConnectedSocket, OnGatewayInit, OnGatewayConnection, OnGatewayDisconnect, } from '@nestjs/websockets'; import { UseGuards, UsePipes, UseFilters, ValidationPipe, } from '@nestjs/common'; import { UwsSocket } from 'uwestjs'; @UseFilters(WsExceptionFilter) @WebSocketGateway() export class ChatGateway implements OnGatewayInit, OnGatewayConnection, OnGatewayDisconnect { afterInit(server: any) { console.log('Gateway initialized'); } handleConnection(client: UwsSocket) { console.log(`Client connected: ${client.id}`); client.join('lobby'); } handleDisconnect(client: UwsSocket) { console.log(`Client disconnected: ${client.id}`); } @SubscribeMessage('message') @UsePipes(new ValidationPipe()) handleMessage( @MessageBody() dto: MessageDto, @ConnectedSocket() client: UwsSocket, ) { client.broadcast.emit('message', { from: client.id, content: dto.content, }); return { event: 'message-sent', data: { id: Date.now() } }; } @SubscribeMessage('secure-action') @UseGuards(WsAuthGuard) handleSecureAction( @MessageBody() data: any, @ConnectedSocket() client: UwsSocket, ) { return { event: 'success', data }; } } ``` -------------------------------- ### Get request header with header() Source: https://uwest.js.org/docs/http-request Shows how to get a request header value using the header() method, which is an alias for get(). ```typescript header(name: string): string | string[] | undefined ``` ```typescript @Get() handler(@Req() req: UwsRequest) { const userAgent = req.header('User-Agent'); } ``` -------------------------------- ### Configure SSL/TLS with cert_file_name, key_file_name, and passphrase Source: https://uwest.js.org/docs/uwsadapter Example showing how to configure SSL/TLS for UwsAdapter with certificate file, private key file, and passphrase. ```typescript new UwsAdapter(app, { port: 8099, cert_file_name: './certs/server.crt', key_file_name: './certs/server.key', passphrase: 'your-passphrase', }); ``` -------------------------------- ### header() Source: https://uwest.js.org/docs/http-request Alias for get(). Get a request header value. ```APIDOC ## Method: header() ### Description Alias for `get()`. Get a request header value. ### Signature ```typescript header(name: string): string | string[] | undefined ``` ### Parameters - `name` (string) - Required - Header name ### Returns Header value or undefined ### Example ```typescript @Get() handler(@Req() req: UwsRequest) { const userAgent = req.header('User-Agent'); } ``` ``` -------------------------------- ### SSL/TLS options example Source: https://uwest.js.org/docs/http-server Configures HTTPS server with SSL certificates. Requires key_file_name, cert_file_name, and optionally passphrase. ```typescript new UwsPlatformAdapter({ key_file_name: '/path/to/private-key.pem', cert_file_name: '/path/to/certificate.pem', passphrase: 'your-passphrase', }) ``` -------------------------------- ### afterInit() Source: https://uwest.js.org/docs/lifecycle Called after the gateway is initialized and registered with the adapter. Use this hook to initialize gateway state, load configuration or data, set up periodic tasks, or log gateway startup. ```APIDOC ## afterInit() ### Description Called after the gateway is initialized and registered with the adapter. Use this hook to initialize gateway state, load configuration or data, set up periodic tasks, or log gateway startup. ### Method Hook (lifecycle) ### Signature `afterInit(server: any): void` ### Parameters - **server** (any) - The WebSocket server instance. ### Use Cases - Initialize gateway state - Load configuration or data - Set up periodic tasks - Log gateway startup ### Example ```typescript import { OnGatewayInit } from '@nestjs/websockets'; @WebSocketGateway() export class ChatGateway implements OnGatewayInit { afterInit(server: any) { console.log('Gateway initialized'); // Perform initialization tasks // - Load initial data // - Set up timers // - Configure gateway state } } ``` ### Advanced Example ```typescript import { OnModuleDestroy } from '@nestjs/common'; import { WebSocketGateway, OnGatewayInit } from '@nestjs/websockets'; @WebSocketGateway() export class GameGateway implements OnGatewayInit, OnModuleDestroy { private games = new Map(); private cleanupInterval?: NodeJS.Timeout; afterInit(server: any) { console.log('Game gateway initialized'); // Load active games from database this.loadActiveGames(); // Start cleanup timer this.cleanupInterval = setInterval(() => { this.cleanupInactiveGames(); }, 60000); // Every minute } onModuleDestroy() { // Clean up interval timer to prevent resource leak if (this.cleanupInterval) { clearInterval(this.cleanupInterval); this.cleanupInterval = undefined; } } private async loadActiveGames() { const games = await this.gameService.findActive(); games.forEach(game => { this.games.set(game.id, game); }); console.log(`Loaded ${games.length} active games`); } private cleanupInactiveGames() { // Cleanup logic } } ``` ``` -------------------------------- ### get() Source: https://uwest.js.org/docs/http-request Method to get a request header value (case-insensitive). ```APIDOC ## Method: get() ### Description Get a request header value (case-insensitive). ### Signature ```typescript get(name: string): string | string[] | undefined ``` ### Parameters - `name` (string) - Required - Header name ### Returns Header value or undefined ### Example ```typescript @Get() handler(@Req() req: UwsRequest) { const contentType = req.get('Content-Type'); const auth = req.get('Authorization'); const customHeader = req.get('X-Custom-Header'); } ``` ``` -------------------------------- ### removeHeader() usage example Source: https://uwest.js.org/docs/http-response Example of setting and then removing a custom header. ```typescript @Get() handler(@Res() res: UwsResponse) { res.setHeader('X-Custom', 'value'); res.removeHeader('X-Custom'); } ``` -------------------------------- ### hasHeader() usage example Source: https://uwest.js.org/docs/http-response Example of checking for a header before setting it to avoid overwriting. ```typescript @Get() handler(@Res() res: UwsResponse) { if (!res.hasHeader('Content-Type')) { res.setHeader('Content-Type', 'text/plain'); } } ``` -------------------------------- ### Accessing the uWS app with getHttpServer() Source: https://uwest.js.org/docs/http-server Example showing how to retrieve the underlying uWebSockets.js server instance using getHttpServer(). ```typescript const adapter = app.getHttpAdapter(); const uwsApp = adapter.getHttpServer(); ``` -------------------------------- ### getHeader() usage example Source: https://uwest.js.org/docs/http-response Example of retrieving a header value case-insensitively after setting it. ```typescript @Get() handler(@Res() res: UwsResponse) { res.setHeader('Content-Type', 'application/json'); console.log(res.getHeader('content-type')); // 'application/json' } ``` -------------------------------- ### setCookie() usage example Source: https://uwest.js.org/docs/http-response Example of setting simple, optioned, signed, and deleted cookies. ```typescript @Get() handler(@Res() res: UwsResponse) { // Simple cookie res.setCookie('session', 'abc123'); // With options res.setCookie('session', 'abc123', { path: '/api', httpOnly: true, secure: true, maxAge: 3600, sameSite: 'strict', }); // Signed cookie res.setCookie('auth', 'token123', { secret: 'my-secret', httpOnly: true, }); // Delete cookie res.setCookie('session', null); } ``` -------------------------------- ### clearCookie() usage example Source: https://uwest.js.org/docs/http-response Example of clearing cookies with and without options, then sending a JSON response. ```typescript @Get('logout') handler(@Res() res: UwsResponse) { res.clearCookie('session'); res.clearCookie('auth', { path: '/api' }); res.json({ message: 'Logged out' }); } ``` -------------------------------- ### cookie() usage example Source: https://uwest.js.org/docs/http-response Example of setting string, object, maxAge, signed, and secure cookies. ```typescript @Get() handler(@Res() res: UwsResponse) { // String value res.cookie('name', 'value'); // Object value (auto-serialized) res.cookie('cart', { items: [1, 2, 3] }); // With maxAge (milliseconds) res.cookie('session', 'abc', { maxAge: 900000 }); // 15 minutes // Signed cookie res.cookie('user', 'john', { signed: true, secret: 'my-secret', }); // Secure cookie res.cookie('auth', 'token', { httpOnly: true, secure: true, sameSite: 'strict', }); } ``` -------------------------------- ### Correct Initialization Pattern for uWS Source: https://uwest.js.org/docs/http-server The correct pattern for uWS adapters: call app.init() to set up routes and middleware, then adapter.listen() to start the server. ```typescript // Correct pattern for uWS await app.init(); adapter.listen(3000, callback); ``` -------------------------------- ### Get request hostname Source: https://uwest.js.org/docs/http-request Shows how to get the hostname from the Host header. Respects X-Forwarded-Host when trustProxy is enabled. ```typescript readonly hostname: string ``` ```typescript @Get() handler(@Req() req: UwsRequest) { console.log(req.hostname); // 'example.com' } ``` -------------------------------- ### SSL/TLS performance options for UwsPlatformAdapter Source: https://uwest.js.org/docs/http-server Example of configuring SSL/TLS with key and cert files and reducing memory usage. ```typescript new UwsPlatformAdapter({ key_file_name: '/path/to/key.pem', cert_file_name: '/path/to/cert.pem', ssl_prefer_low_memory_usage: true, // Reduce memory usage }) ``` -------------------------------- ### json() usage example Source: https://uwest.js.org/docs/http-response Example of using res.json() to send a JSON response with a status and data object. ```typescript @Get() handler(@Res() res: UwsResponse) { res.json({ status: 'success', data: { id: 1, name: 'John' }, }); } ``` -------------------------------- ### append() usage example Source: https://uwest.js.org/docs/http-response Example of appending multiple values to the Set-Cookie header, resulting in an array of values. ```typescript @Get() handler(@Res() res: UwsResponse) { res.append('Set-Cookie', 'session=abc'); res.append('Set-Cookie', 'user=123'); // Results in: ['session=abc', 'user=123'] } ``` -------------------------------- ### Serve Documentation Site with useStaticAssets Source: https://uwest.js.org/docs/static-files Configures static file serving for a documentation site with a '/docs' prefix, index files, cache max age of 1 hour, and ETag support. Note that serving raw markdown files like README.md will display as plain text, not rendered HTML. ```typescript app.useStaticAssets('docs', { prefix: '/docs', index: ['index.html', 'index.htm'], maxAge: '1h', etag: true, }); ``` -------------------------------- ### attachment() usage example Source: https://uwest.js.org/docs/http-response Example of using attachment() with and without a filename, and how it auto-sets Content-Type based on the file extension. ```typescript @Get('download') handler(@Res() res: UwsResponse) { // Without filename res.attachment(); // With filename res.attachment('report.pdf'); res.send(pdfBuffer); // Auto-sets Content-Type based on extension res.attachment('document.pdf'); // Sets application/pdf res.attachment('image.png'); // Sets image/png } ``` -------------------------------- ### Game Gateway with create-game, join-game, and game-action handlers Source: https://uwest.js.org/docs/rooms Implements game rooms with unique room names like 'game:gameId'. Handles creating a game, joining it, and broadcasting game actions to all players. Throws WsException if a client not in a game attempts an action. ```typescript import { WsException } from 'uwestjs'; @WebSocketGateway() export class GameGateway { @SubscribeMessage('create-game') handleCreateGame( @MessageBody() settings: any, @ConnectedSocket() client: UwsSocket, ) { const gameId = this.generateGameId(); const roomName = `game:${gameId}`; client.join(roomName); client.data.gameId = gameId; return { event: 'game-created', gameId }; } @SubscribeMessage('join-game') handleJoinGame( @MessageBody() gameId: string, @ConnectedSocket() client: UwsSocket, ) { const roomName = `game:${gameId}`; client.join(roomName); client.data.gameId = gameId; // Notify all players client.to(roomName).emit('player-joined', { playerId: client.id, username: client.data?.user?.name, }); } @SubscribeMessage('game-action') handleGameAction( @MessageBody() action: any, @ConnectedSocket() client: UwsSocket, ) { const gameId = client.data.gameId; if (!gameId) { throw new WsException('Not in a game'); } // Broadcast action to all players in the game client.to(`game:${gameId}`).emit('game-update', { playerId: client.id, action, }); } } ``` -------------------------------- ### pipeFrom() usage example Source: https://uwest.js.org/docs/http-response Example of using res.pipeFrom() to stream a PDF file with Content-Type and Content-Disposition headers set. ```typescript @Get('download') handler(@Res() res: UwsResponse) { const fileStream = fs.createReadStream('document.pdf'); res.setHeader('Content-Type', 'application/pdf'); res.setHeader('Content-Disposition', 'attachment; filename="document.pdf"'); res.pipeFrom(fileStream); } ``` -------------------------------- ### Integrate with existing uWS app using uwsApp Source: https://uwest.js.org/docs/uwsadapter Example showing how to provide an existing uWebSockets.js app instance to share between HTTP and WebSocket adapters. ```typescript import { App } from 'uwestjs'; const uwsApp = App(); // HTTP adapter const httpAdapter = new UwsPlatformAdapter(uwsApp); const app = await NestFactory.create(AppModule, httpAdapter); // WebSocket adapter (shares the same uWS instance) const wsAdapter = new UwsAdapter(app, { uwsApp }); app.useWebSocketAdapter(wsAdapter); ``` -------------------------------- ### end() usage example Source: https://uwest.js.org/docs/http-response Example of using res.end() after writing chunks with writeChunk(). The callback logs when the response is sent. ```typescript @Get() handler(@Res() res: UwsResponse) { res.writeChunk('Part 1\n'); res.writeChunk('Part 2\n'); res.end('Final part', () => { console.log('Response sent'); }); } ``` -------------------------------- ### handleConnection() basic example Source: https://uwest.js.org/docs/lifecycle Basic implementation of the handleConnection hook, called when a client connects. Logs the client ID and provides comments for typical tasks. ```typescript import { OnGatewayConnection } from '@nestjs/websockets'; @WebSocketGateway() export class ChatGateway implements OnGatewayConnection { handleConnection(client: any) { console.log(`Client connected: ${client.id}`); // Handle new connection // - Authenticate client // - Send welcome message // - Join default rooms // - Track connection } } ``` -------------------------------- ### Complete CORS Configuration Example Source: https://uwest.js.org/docs/http-cors Shows how to enable CORS with a specific origin, credentials, custom methods, headers, and a maxAge of 3600 seconds (1 hour). This configuration uses a single origin and credentials, which is allowed per CORS specification. ```typescript app.enableCors({ origin: 'https://example.com', credentials: true, methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH'], allowedHeaders: ['Content-Type', 'Authorization', 'X-API-Key'], exposedHeaders: ['X-Total-Count', 'X-Page-Number'], maxAge: 3600, // 1 hour }); ``` -------------------------------- ### maxBodySize example Source: https://uwest.js.org/docs/http-server Sets the maximum request body size in bytes. Default is 1048576 (1MB). This example sets it to 10MB. ```typescript new UwsPlatformAdapter({ maxBodySize: 10 * 1024 * 1024, // 10MB }) ``` -------------------------------- ### Game gateway with broadcasting to game room Source: https://uwest.js.org/docs/broadcast-operator Full GameGateway example showing how to broadcast game actions to all players in a room and handle state requests with sender-specific responses. ```typescript @WebSocketGateway() export class GameGateway { @SubscribeMessage('game-action') handleGameAction( @MessageBody() action: any, @ConnectedSocket() client: UwsSocket, ) { const gameId = client.data.gameId; const roomName = `game:${gameId}`; // Broadcast action to all players in the game client.to(roomName).emit('game-update', { playerId: client.id, action, timestamp: Date.now(), }); } @SubscribeMessage('game-state-request') handleStateRequest(@ConnectedSocket() client: UwsSocket) { const gameId = client.data.gameId; const roomName = `game:${gameId}`; // Send state to requester const state = this.getGameState(gameId); client.emit('game-state', state); // Notify others that state was requested client.broadcast.to(roomName).emit('state-requested', { playerId: client.id, }); } } ```