I'm sending Apple Push Notifications (APN) from my server with a PHP script. First step is to populate a database table with the device tokens and the message to send. Then my script iterates over these table rows and sends the notifications one by one. The script is invoked by a cronjob every minute and if there are messages in my table it sends at most 50 of them and then it exits. The most important parts of my script are shown below.
I can use this script to send messages to five or ten test devices and all the messages get delivered successfully. But if I use the very same script to send the message to all 300 registered devices, only 50% get delivered. The same device sometimes gets the notifications and sometimes it doesn't. So, I know my script works and I know my devices can receive the notifications, but if I want to send a message to all devices only about a half of the messages are received.
I know that APN does not guarantee to successfully deliver the messages, but a success rate of 50% seems very low to me. Thus, these are my questions:
- What is the typical success rate of messages sent via APN?
- Should I better send all 300 push notifications at once?
- Are there any ways to get error messages from the APN servers?
Here's the code from my script:
// create stream context
$ctx = stream_context_create();
stream_context_set_option(
$ctx,
'ssl',
'local_cert',
'/path/to/push.pem'
);
stream_context_set_option(
$ctx,
'ssl',
'passphrase',
$passphrase
);
// connect with Apple server
$fp = stream_socket_client(
'ssl://gateway.push.apple.com:2195',
$err,
$errstr,
60,
STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT,
$ctx
);
// get next 50 rows from database table
// ...
// for every row in my table
foreach( $rows as $row ) {
$msg = chr(0) . pack('n', 32) . pack('H*', $deviceToken) . pack('n', strlen($payload)) . $payload;
// send a message
$result = fwrite($fp, $msg, strlen($msg));
if( $result ) {
// delete row from database
} else {
// log error
break;
}
}