diff --git a/src/notifications/senders/AppleNotificationSender.ts b/src/notifications/senders/AppleNotificationSender.ts index ebe20f0..ba03989 100644 --- a/src/notifications/senders/AppleNotificationSender.ts +++ b/src/notifications/senders/AppleNotificationSender.ts @@ -18,12 +18,20 @@ export class AppleNotificationSender { private apnsToken: string | undefined = undefined; private _lastRefreshedTimeMs: number | undefined = undefined; - private client: ClientHttp2Session | undefined = undefined; - - constructor(private shouldActuallySendNotifications = true) { + constructor( + private shouldActuallySendNotifications = true, + private client: ClientHttp2Session | undefined = undefined, + ) { this.sendNotificationImmediately = this.sendNotificationImmediately.bind(this); this.lastReloadedTimeForAPNsIsTooRecent = this.lastReloadedTimeForAPNsIsTooRecent.bind(this); this.reloadAPNsTokenIfTimePassed = this.reloadAPNsTokenIfTimePassed.bind(this); + this.openConnectionIfNoneExists = this.openConnectionIfNoneExists.bind(this); + this.closeConnectionIfExists = this.closeConnectionIfExists.bind(this); + this.registerClosureEventsForClient = this.registerClosureEventsForClient.bind(this); + + if (this.client !== undefined) { + this.registerClosureEventsForClient(); + } } get lastRefreshedTimeMs(): number | undefined { @@ -101,8 +109,7 @@ export class AppleNotificationSender { }; try { if (!this.client) { return false } - const client = this.client; - const req = client.request(headers); + const req = this.client.request(headers); req.setEncoding('utf8'); await new Promise((resolve, reject) => { @@ -142,9 +149,17 @@ export class AppleNotificationSender { if (!this.client) { this.client = http2.connect(host); + this.registerClosureEventsForClient(); } } + private registerClosureEventsForClient() { + this.client?.on('close', this.closeConnectionIfExists); + this.client?.on('error', this.closeConnectionIfExists); + this.client?.on('goaway', this.closeConnectionIfExists); + this.client?.on('timeout', this.closeConnectionIfExists); + } + private closeConnectionIfExists() { this.client?.close(); this.client = undefined; diff --git a/test/notifications/senders/AppleNotificationSenderTests.test.ts b/test/notifications/senders/AppleNotificationSenderTests.test.ts index 67c38f3..bd7f9ef 100644 --- a/test/notifications/senders/AppleNotificationSenderTests.test.ts +++ b/test/notifications/senders/AppleNotificationSenderTests.test.ts @@ -168,7 +168,7 @@ describe("AppleNotificationSender", () => { }); it("registers a handler to close the connection if `close` event fired", async () => { - const connectionCloseEvents = ['close', 'goaway', 'error']; + const connectionCloseEvents = ['close', 'goaway', 'error', 'timeout']; await Promise.all(connectionCloseEvents.map(async (event) => { const mockClient = new MockClient(200); @@ -179,7 +179,7 @@ describe("AppleNotificationSender", () => { body: '' }; - const result = await notificationSender.sendNotificationImmediately('1', notificationArguments); + await notificationSender.sendNotificationImmediately('1', notificationArguments); mockClient.emit(event);