From e1bcfcfc0543d042c92e05472159ec4e9ef7a779 Mon Sep 17 00:00:00 2001 From: tharu-jwd Date: Fri, 10 Apr 2026 12:20:52 +0530 Subject: [PATCH] fix: close dead connections with active subscriptions on heartbeat timeout --- src/adapters/web-socket-adapter.ts | 2 +- test/unit/adapters/web-socket-adapter.spec.ts | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/adapters/web-socket-adapter.ts b/src/adapters/web-socket-adapter.ts index 989c6083..cd81e8e6 100644 --- a/src/adapters/web-socket-adapter.ts +++ b/src/adapters/web-socket-adapter.ts @@ -126,7 +126,7 @@ export class WebSocketAdapter extends EventEmitter implements IWebSocketAdapter } public onHeartbeat(): void { - if (!this.alive && !this.subscriptions.size) { + if (!this.alive) { logger.error(`web-socket-adapter: pong timeout for client ${this.clientId} (${this.getClientAddress()})`) this.client.close() return diff --git a/test/unit/adapters/web-socket-adapter.spec.ts b/test/unit/adapters/web-socket-adapter.spec.ts index a6517509..be535c38 100644 --- a/test/unit/adapters/web-socket-adapter.spec.ts +++ b/test/unit/adapters/web-socket-adapter.spec.ts @@ -216,15 +216,15 @@ describe('WebSocketAdapter', () => { expect(client.close).to.have.been.calledOnce }) - it('does not close when client is not alive but has subscriptions', () => { + it('closes when client is not alive even if it has active subscriptions', () => { adapter.onSubscribed('sub-1', [{ kinds: [1] }]) // First heartbeat: sets alive to false, pings adapter.emit(WebSocketAdapterEvent.Heartbeat) - // Second heartbeat: alive is false, but has subs -> keep alive + // Second heartbeat: alive is still false, has subs -> still close adapter.emit(WebSocketAdapterEvent.Heartbeat) - expect(client.close).not.to.have.been.called + expect(client.close).to.have.been.called }) })