From a2b2dc1a560ce3cf55d925510f319d989c820632 Mon Sep 17 00:00:00 2001 From: Juergen Kunz Date: Mon, 23 Mar 2026 10:31:54 +0000 Subject: [PATCH] fix(adapter.node): close websocket server and active connections when stopping the Node adapter --- changelog.md | 6 ++++++ ts/00_commitinfo_data.ts | 2 +- ts/adapters/adapter.node.ts | 14 ++++++++++---- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/changelog.md b/changelog.md index 81bbfbe..05b6cda 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,11 @@ # Changelog +## 2026-03-23 - 2.0.2 - fix(adapter.node) +close websocket server and active connections when stopping the Node adapter + +- Store the WebSocketServer instance on the adapter so it can be closed during shutdown. +- Close all active HTTP connections before closing the underlying Node server to improve shutdown cleanup. + ## 2025-12-20 - 2.0.1 - fix(readme) update README: rework features, add OpenAPI/Swagger, compression, request validation, examples, and runtime stats diff --git a/ts/00_commitinfo_data.ts b/ts/00_commitinfo_data.ts index 961eb5f..63ba2f4 100644 --- a/ts/00_commitinfo_data.ts +++ b/ts/00_commitinfo_data.ts @@ -3,6 +3,6 @@ */ export const commitinfo = { name: '@push.rocks/smartserve', - version: '2.0.1', + version: '2.0.2', description: 'a cross platform server module for Node, Deno and Bun' } diff --git a/ts/adapters/adapter.node.ts b/ts/adapters/adapter.node.ts index 7cb1115..e07c167 100644 --- a/ts/adapters/adapter.node.ts +++ b/ts/adapters/adapter.node.ts @@ -7,6 +7,7 @@ import { BaseAdapter, type IAdapterCharacteristics, type TRequestHandler } from */ export class NodeAdapter extends BaseAdapter { private server: plugins.http.Server | plugins.https.Server | null = null; + private wss: any = null; get name(): 'node' { return 'node'; @@ -92,8 +93,13 @@ export class NodeAdapter extends BaseAdapter { } async stop(): Promise { + if (this.wss) { + this.wss.close(); + this.wss = null; + } return new Promise((resolve, reject) => { if (this.server) { + this.server.closeAllConnections(); this.server.close((err) => { if (err) reject(err); else resolve(); @@ -254,19 +260,19 @@ export class NodeAdapter extends BaseAdapter { // Dynamic import of ws library const { WebSocketServer } = await import('ws'); - const wss = new WebSocketServer({ noServer: true }); + this.wss = new WebSocketServer({ noServer: true }); // Get internal callbacks if typedRouter mode const callbacks = (hooks as any)._connectionCallbacks as IWebSocketConnectionCallbacks | undefined; const typedRouter = hooks.typedRouter; this.server.on('upgrade', (request, socket, head) => { - wss.handleUpgrade(request, socket, head, (ws) => { - wss.emit('connection', ws, request); + this.wss.handleUpgrade(request, socket, head, (ws: any) => { + this.wss.emit('connection', ws, request); }); }); - wss.on('connection', (ws: any, request: any) => { + this.wss.on('connection', (ws: any, request: any) => { const peer = this.wrapNodeWebSocket(ws, request); // Register connection if typedRouter mode