I need to send thousands (actually 10 000) push notifications at the same time, to do this, I checked StackOverflow and found those two questions:
- Apple Push Notification: Sending high volumes of messages
- Apple Push Notification: Sending high volumes of messages
And I implemented my push system using php:
// Create the payload body
$body['aps'] = [
'alert' => $notification->getMessage(),//$notification is just a notification model, where getMessage() returns the message I want to send as string
'sound' => 'default'
];
// Encode the payload as JSON
$payload = json_encode($body);
$fp = self::createSocket();
foreach($devices as $device) {
$token = $device->getToken();
$msg = chr(0) . pack('n', 32) . pack('H*', str_replace(' ', '', $token)) . pack('n', strlen($payload)) . $payload;
if(!self::sendSSLMessage($fp, $msg)){
//$msg is a parameter of the method, it's the message as string
fclose($fp);
$fp = self::createSocket();
}else{
//Here I log "n notification sent" every 100 notifications
}
}
fclose($fp);
Here is the createSocket()
method:
private static function createSocket(){
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', PUSH_IOS_CERTIFICAT_LOCATION);
stream_context_set_option($ctx, 'ssl', 'passphrase', PUSH_IOS_PARAPHRASE);
// Open a connection to the APNS server
$fp = stream_socket_client(
'ssl://gateway.push.apple.com:2195', $err,
$errstr, 60, STREAM_CLIENT_CONNECT, $ctx);
stream_set_blocking ($fp, 0);
if (!$fp) {
FileLog::log("Ios failed to connect: $err $errstr");
}
return $fp;
}
And the sendSSLMessage()
method:
private static function sendSSLMessage($fp, $msg, $tries = 0){
if($tries >= 10){
return false;
}
return fwrite($fp, $msg, strlen($msg)) ? self::sendSSLMessage($fp, $msg, $tries++) : true;
}
I'm not getting any error message from apple, everything looks fine except nobody is receiving the notification.
Before this, I was using a method creating one socket connection per message and closing it after sending the message, but it was way too slow so we decided to change it, so I know that it's not a client related issue.