diff --git a/integration/websockets/e2e/ws-gateway.spec.ts b/integration/websockets/e2e/ws-gateway.spec.ts index de4daf9889e..c68883ba3fd 100644 --- a/integration/websockets/e2e/ws-gateway.spec.ts +++ b/integration/websockets/e2e/ws-gateway.spec.ts @@ -106,8 +106,8 @@ describe('WebSocketGateway (WsAdapter)', () => { // open websockets delay await new Promise(resolve => setTimeout(resolve, 1000)); - ws = new WebSocket('ws://localhost:8082/example'); - ws2 = new WebSocket('ws://localhost:8082/ws-path'); + ws = new WebSocket('ws://localhost:3000/example'); + ws2 = new WebSocket('ws://localhost:3000/ws-path'); await new Promise(resolve => ws.on('open', () => { diff --git a/integration/websockets/src/example-path.gateway.ts b/integration/websockets/src/example-path.gateway.ts index 31c4b2c63b0..728e2fb3207 100644 --- a/integration/websockets/src/example-path.gateway.ts +++ b/integration/websockets/src/example-path.gateway.ts @@ -1,6 +1,6 @@ import { SubscribeMessage, WebSocketGateway } from '@nestjs/websockets'; -@WebSocketGateway(8082, { +@WebSocketGateway({ path: '/example', }) export class ExamplePathGateway { diff --git a/integration/websockets/src/ws-path2.gateway.ts b/integration/websockets/src/ws-path2.gateway.ts index 0c4a9d69d21..2334950eb68 100644 --- a/integration/websockets/src/ws-path2.gateway.ts +++ b/integration/websockets/src/ws-path2.gateway.ts @@ -1,6 +1,6 @@ import { SubscribeMessage, WebSocketGateway } from '@nestjs/websockets'; -@WebSocketGateway(8082, { +@WebSocketGateway({ path: '/ws-path', }) export class WsPathGateway2 { diff --git a/package.json b/package.json index d4100d6d252..539a2a1fd6f 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "format": "prettier \"**/*.ts\" --ignore-path ./.prettierignore --write && git status", "postinstall": "opencollective", "test": "nyc --require ts-node/register mocha packages/**/*.spec.ts --reporter spec --require 'node_modules/reflect-metadata/Reflect.js' --exit", - "test:integration": "mocha \"integration/*/{,!(node_modules)/**/}/*.spec.ts\" --reporter spec --require ts-node/register --require 'node_modules/reflect-metadata/Reflect.js' --exit", + "test:integration": "mocha \"integration/websockets/{,!(node_modules)/**/}/*.spec.ts\" --reporter spec --require ts-node/register --require 'node_modules/reflect-metadata/Reflect.js' --exit", "test:docker:up": "docker-compose -f integration/docker-compose.yml up -d", "test:docker:down": "docker-compose -f integration/docker-compose.yml down", "lint": "concurrently 'npm run lint:packages' 'npm run lint:integration' 'npm run lint:spec'", diff --git a/packages/platform-ws/adapters/ws-adapter.ts b/packages/platform-ws/adapters/ws-adapter.ts index b0047dc8926..cca1f81a62d 100644 --- a/packages/platform-ws/adapters/ws-adapter.ts +++ b/packages/platform-ws/adapters/ws-adapter.ts @@ -45,8 +45,8 @@ export class WsAdapter extends AbstractWsAdapter { public create( port: number, - options?: any & { namespace?: string; server?: any }, - ): any { + options?: Record & { namespace?: string; server?: any }, + ) { const { server, ...wsOptions } = options; if (wsOptions?.namespace) { const error = new Error( @@ -55,24 +55,29 @@ export class WsAdapter extends AbstractWsAdapter { this.logger.error(error); throw error; } + if (port === UNDERLYING_HTTP_SERVER_PORT && this.httpServer) { - return this.bindErrorHandler( + this.ensureHttpServerExists(port, this.httpServer); + const wsServer = this.bindErrorHandler( new wsPackage.Server({ - server: this.httpServer, + noServer: true, ...wsOptions, }), ); + + this.addWsServerToRegistry(wsServer, port, options.path || '/'); + return wsServer; } if (server) { - // When server exists already return server; } if (options.path && port !== UNDERLYING_HTTP_SERVER_PORT) { // Multiple servers with different paths // sharing a single HTTP/S server running on different port // than a regular HTTP application - this.ensureHttpServerExists(port); + const httpServer = this.ensureHttpServerExists(port); + httpServer?.listen(port); const wsServer = this.bindErrorHandler( new wsPackage.Server({ @@ -145,19 +150,22 @@ export class WsAdapter extends AbstractWsAdapter { } public async dispose() { - const closeEvents = Array.from(this.httpServersRegistry).map( - ([_, server]) => new Promise(resolve => server.close(resolve)), - ); - await Promise.all(closeEvents); + const closeEventSignals = Array.from(this.httpServersRegistry) + .filter(([port]) => port !== UNDERLYING_HTTP_SERVER_PORT) + .map(([_, server]) => new Promise(resolve => server.close(resolve))); + + await Promise.all(closeEventSignals); this.httpServersRegistry.clear(); this.wsServersRegistry.clear(); } - protected ensureHttpServerExists(port: number) { + protected ensureHttpServerExists( + port: number, + httpServer = http.createServer(), + ) { if (this.httpServersRegistry.has(port)) { return; } - const httpServer = http.createServer(); this.httpServersRegistry.set(port, httpServer); httpServer.on('upgrade', (request, socket, head) => { @@ -179,8 +187,7 @@ export class WsAdapter extends AbstractWsAdapter { socket.destroy(); } }); - - httpServer.listen(port); + return httpServer; } protected addWsServerToRegistry = any>(