David
David

Reputation: 3348

Sending Apple Push Notification via PHP: unable to connect to ssl://gateway.sandbox.push.apple.com:2195 (Connection timed out)

I have the following PHP code to send Apple Push Notifications to my app:

<?php
$body = '{"aps":{"alert":{"title":"test title","subtitle":"","body":"test body"},"badge":0,"sound":"default","additional_data":"test additional_data"}}';

$context = stream_context_create();
stream_context_set_option($context, "ssl", "local_cert", "certificate.pem");
stream_context_set_option($context, "ssl", "passphrase", "HERE_COMES_THE_PASSWORD_OF_THE_certificate.pem_FILE");
$socket = stream_socket_client("ssl://gateway.sandbox.push.apple.com:2195", $error, $errstr, 30, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $context);
$msg = chr(0) . chr(0) . chr(32) . pack("H*", "HERE_COMES_MY_APPLE_PUSH_TOKEN") . pack("n", strlen($body)) . $body;
$result = fwrite($socket, $msg, strlen($msg));
fclose($socket);
?>

This code is stored on my server together with the certificate file called certificate.pem.

I'm using this code unchanged since month without any problems. Today, I noticed, that I'm not getting push notifications any more.

The PHP error log shows the following:

[23-Mar-2022 11:39:45 UTC] PHP Warning:  stream_socket_client(): unable to connect to ssl://gateway.sandbox.push.apple.com:2195 (Connection timed out) in /home2/kd37875/public_html/test/index.php on line 7
[23-Mar-2022 11:39:45 UTC] PHP Warning:  fwrite() expects parameter 1 to be resource, bool given in /home2/kd37875/public_html/test/index.php on line 9
[23-Mar-2022 11:39:45 UTC] PHP Warning:  fclose() expects parameter 1 to be resource, bool given in /home2/kd37875/public_html/test/index.php on line 10

First, I thought, there's something wrong with the certificate file. Then, I found this: https://www.pushtry.com website. If I insert the Device Token, upload the certificate.pem file, insert the Bundle ID and a message, I'm successfully receiving a push message in my app. (There's a field for password on the website but it's also working if I don't insert it. No idea, why.) So this says me, that the certificate.pem must be okay.

screenshot from https://www.pushtry.com

Do you have any idea what I'm doing wrong? Why doesn't it work any more? Did Apple change something?

Upvotes: 0

Views: 2029

Answers (1)

David
David

Reputation: 3348

I finally solved my problem. Apple made a change to this about a year ago. No idea why it affected me only today.

This is the working code:

<?php
function sendHTTP2Push($http2_server, $apple_cert, $app_bundle_id, $message, $token) {
if(!defined('CURL_HTTP_VERSION_2_0')) {
    define('CURL_HTTP_VERSION_2_0', 3);
}
$http2ch = curl_init();
curl_setopt($http2ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0);

curl_setopt_array($http2ch, array(
    CURLOPT_URL => "{$http2_server}/3/device/{$token}",
    CURLOPT_PORT => 443,
    CURLOPT_HTTPHEADER => array("apns-topic: {$app_bundle_id}"),
    CURLOPT_POST => TRUE,
    CURLOPT_POSTFIELDS => $message,
    CURLOPT_RETURNTRANSFER => TRUE,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_SSL_VERIFYPEER => false,
    CURLOPT_SSLCERT => realpath($apple_cert),
    CURLOPT_HEADER => 1
));

$result = curl_exec($http2ch);
if($result === FALSE) {
    throw new Exception('Curl failed with error: ' . curl_error($http2ch));
}

$status = curl_getinfo($http2ch, CURLINFO_HTTP_CODE);
return $status;

curl_close($http2ch);
}

$status = sendHTTP2Push('https://api.development.push.apple.com', 'certificate.pem', 'HERE_COMES_THE_APPS_BUNDLE_ID', '{"aps":{"alert":{"title":"test title","subtitle":"","body":"test body"},"badge":0,"sound":"default","additional_data":"test additional_data"}}', 'HERE_COMES_MY_APPLE_PUSH_TOKEN');

echo "Response code: ".$status;
?>

Source: https://gist.github.com/valfer/18e1052bd4b160fed86e6cbb426bb9fc

Upvotes: 2

Related Questions