Skip to content

Commit 20fc514

Browse files
committed
reduce use of callbacks
1 parent 1efd838 commit 20fc514

File tree

6 files changed

+55
-36
lines changed

6 files changed

+55
-36
lines changed

README.md

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ var options = {
5959
production: false
6060
};
6161

62-
var apnProvider = new apn.Provider(options);
62+
const apnProvider = new apn.Provider(options);
6363
```
6464

6565
By default, the provider will connect to the sandbox unless the environment variable `NODE_ENV=production` is set.
@@ -68,6 +68,10 @@ For more information about configuration options consult the [provider documenta
6868

6969
Help with preparing the key and certificate files for connection can be found in the [wiki][certificateWiki]
7070

71+
⚠️ You should only create one `Provider` per-process for each certificate/key pair you have. You do not need to create a new `Provider` for each notification. If you are only sending notifications to one app then there is no need for more than one `Provider`.
72+
73+
If you are constantly creating `Provider` instances in your app, make sure to call `Provider.shutdown()` when you are done with each provider to release its resources and memory.
74+
7175
### Connecting through an HTTP proxy
7276

7377
If you need to connect through an HTTP proxy, you simply need to provide the `proxy: {host, port}` option when creating the provider. For example:
@@ -86,7 +90,7 @@ var options = {
8690
production: false
8791
};
8892

89-
var apnProvider = new apn.Provider(options);
93+
const apnProvider = new apn.Provider(options);
9094
```
9195

9296
The provider will first send an HTTP CONNECT request to the specified proxy in order to establish an HTTP tunnel. Once established, it will create a new secure connection to the Apple Push Notification provider API through the tunnel.
@@ -111,7 +115,7 @@ var options = {
111115
production: false
112116
};
113117

114-
var apnProvider = new apn.MultiProvider(options);
118+
const apnProvider = new apn.MultiProvider(options);
115119
```
116120

117121
## Sending a notification
@@ -124,7 +128,7 @@ let deviceToken = "a9d0ed10e9cfd022a61cb08753f49c5a0b0dfb383697bf9f9d750a1003da1
124128
Create a notification object, configuring it with the relevant parameters (See the [notification documentation](doc/notification.markdown) for more details.)
125129

126130
```javascript
127-
var note = new apn.Notification();
131+
let note = new apn.Notification();
128132

129133
note.expiry = Math.floor(Date.now() / 1000) + 3600; // Expires 1 hour from now.
130134
note.badge = 3;
@@ -137,9 +141,12 @@ note.topic = "<your-app-bundle-id>";
137141
Send the notification to the API with `send`, which returns a promise.
138142

139143
```javascript
140-
apnProvider.send(note, deviceToken).then( (result) => {
144+
try {
145+
const result = apnProvider.send(note, deviceToken);
141146
// see documentation for an explanation of result
142-
});
147+
} catch(error) {
148+
// Handle error...
149+
}
143150
```
144151

145152
This will result in the the following notification payload being sent to the device
@@ -151,7 +158,7 @@ This will result in the the following notification payload being sent to the dev
151158
Create a Live Activity notification object, configuring it with the relevant parameters (See the [notification documentation](doc/notification.markdown) for more details.)
152159

153160
```javascript
154-
var note = new apn.Notification();
161+
let note = new apn.Notification();
155162

156163
note.expiry = Math.floor(Date.now() / 1000) + 3600; // Expires 1 hour from now.
157164
note.badge = 3;
@@ -170,9 +177,12 @@ note.contentState = {}
170177
Send the notification to the API with `send`, which returns a promise.
171178

172179
```javascript
173-
apnProvider.send(note, deviceToken).then( (result) => {
180+
try {
181+
const result = await apnProvider.send(note, deviceToken)
174182
// see documentation for an explanation of result
175-
});
183+
} catch (error) {
184+
// Handle error...
185+
}
176186
```
177187

178188
This will result in the the following notification payload being sent to the device
@@ -182,6 +192,6 @@ This will result in the the following notification payload being sent to the dev
182192
{"messageFrom":"John Appleseed","aps":{"badge":3,"sound":"ping.aiff","alert":"\uD83D\uDCE7 \u2709 You have a new message", "relevance-score":75,"timestamp":1683129662,"stale-date":1683216062,"event":"update","content-state":{}}}
183193
```
184194

185-
You should only create one `Provider` per-process for each certificate/key pair you have. You do not need to create a new `Provider` for each notification. If you are only sending notifications to one app then there is no need for more than one `Provider`.
195+
## Manage Channels
186196

187-
If you are constantly creating `Provider` instances in your app, make sure to call `Provider.shutdown()` when you are done with each provider to release its resources and memory.
197+
## Sending Broadcast Notifications

doc/provider.markdown

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ If you wish to send notifications containing emoji or other multi-byte character
103103

104104
Indicate to node-apn that it should close all open connections when the queue of pending notifications is fully drained. This will allow your application to terminate.
105105

106-
**Note:** If notifications are pushed after the connection has started, an error will be thrown.
106+
**Note:** If notifications are pushed after the shutdown has started, an error will be thrown.
107107

108108
[provider-api]: https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/CommunicatingwithAPNs.html
109109
[provider-auth-tokens]: https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/CommunicatingwithAPNs.html#//apple_ref/doc/uid/TP40008194-CH11-SW1

index.d.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ export class Provider extends EventEmitter {
192192
/**
193193
* Indicate to node-apn that it should close all open connections when the queue of pending notifications is fully drained. This will allow your application to terminate.
194194
*/
195-
shutdown(callback?: () => void): void;
195+
shutdown(callback?: () => void): Promise<void>;
196196
}
197197

198198
export class MultiProvider extends EventEmitter {
@@ -238,7 +238,7 @@ export class MultiProvider extends EventEmitter {
238238
/**
239239
* Indicate to node-apn that it should close all open connections when the queue of pending notifications is fully drained. This will allow your application to terminate.
240240
*/
241-
shutdown(callback?: () => void): void;
241+
shutdown(callback?: () => void): Promise<void>;
242242
}
243243

244244
export type NotificationPushType = 'background' | 'alert' | 'voip' | 'pushtotalk' | 'liveactivity' | 'location' | 'complication' | 'fileprovider' | 'mdm';

lib/client.js

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -74,28 +74,19 @@ module.exports = function (dependencies) {
7474
}, this.config.heartBeat).unref();
7575
}
7676

77-
Client.prototype.destroySession = function (session, callback) {
77+
Client.prototype.destroySession = function (session) {
7878
if (!session) {
79-
if (callback) {
80-
callback();
81-
}
8279
return;
8380
}
8481
if (!session.destroyed) {
8582
session.destroy();
8683
}
8784
session = null;
88-
if (callback) {
89-
callback();
90-
}
9185
};
9286

9387
// Session should be passed except when destroying the client
94-
Client.prototype.closeAndDestroySession = async function (session, callback) {
88+
Client.prototype.closeAndDestroySession = async function (session) {
9589
if (!session) {
96-
if (callback) {
97-
callback();
98-
}
9990
return;
10091
}
10192
if (!session.closed) {
@@ -105,7 +96,7 @@ module.exports = function (dependencies) {
10596
});
10697
});
10798
}
108-
this.destroySession(session, callback);
99+
this.destroySession(session);
109100
};
110101

111102
Client.prototype.makePath = function makePath(type, subDirectory) {
@@ -667,8 +658,11 @@ module.exports = function (dependencies) {
667658
});
668659
};
669660

670-
Client.prototype.shutdown = async function shutdown() {
661+
Client.prototype.shutdown = async function shutdown(callback) {
671662
if (this.isDestroyed) {
663+
if (callback) {
664+
callback();
665+
}
672666
return;
673667
}
674668
if (this.errorLogger.enabled) {
@@ -685,6 +679,9 @@ module.exports = function (dependencies) {
685679
}
686680
await this.closeAndDestroySession(this.session);
687681
await this.closeAndDestroySession(this.manageChannelsSession);
682+
if (callback) {
683+
callback();
684+
}
688685
};
689686

690687
Client.prototype.setLogger = function (newLogger, newErrorLogger = null) {

lib/multiclient.js

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,19 +30,29 @@ module.exports = function (dependencies) {
3030
return client;
3131
};
3232

33-
MultiClient.prototype.write = function write(notification, device, type, method, count) {
34-
return this.chooseSingleClient().write(notification, device, type, method, count);
33+
MultiClient.prototype.write = async function write(
34+
notification,
35+
subDirectory,
36+
type,
37+
method,
38+
count
39+
) {
40+
return await this.chooseSingleClient().write(notification, subDirectory, type, method, count);
3541
};
3642

37-
MultiClient.prototype.shutdown = function shutdown(callback) {
43+
MultiClient.prototype.shutdown = async function shutdown(callback) {
3844
let callCount = 0;
3945
const multiCallback = () => {
4046
callCount++;
4147
if (callCount === this.clients.length) {
42-
callback();
48+
if (callback) {
49+
callback();
50+
}
4351
}
4452
};
45-
this.clients.forEach(client => client.shutdown(multiCallback));
53+
for (const client of this.clients) {
54+
await client.shutdown(multiCallback);
55+
}
4656
};
4757

4858
MultiClient.prototype.setLogger = function (newLogger, newErrorLogger = null) {

test/multiclient.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,9 @@ describe('MultiClient', () => {
131131
}
132132
};
133133
if (client) {
134-
await client.shutdown(closeServer);
135-
client = null;
134+
await client.shutdown(() => {
135+
client = null;
136+
});
136137
}
137138
await closeServer();
138139
});
@@ -1229,8 +1230,9 @@ describe('ManageChannelsMultiClient', () => {
12291230
}
12301231
};
12311232
if (client) {
1232-
await client.shutdown();
1233-
client = null;
1233+
await client.shutdown(() => {
1234+
client = null;
1235+
});
12341236
}
12351237
await closeServer();
12361238
});

0 commit comments

Comments
 (0)