通过 PHP 发送 Apple 推送通知:无法连接到 ssl://gateway.sandbox.push.apple.com:2195(连接超时)

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

我有以下 PHP 代码将 Apple 推送通知发送到我的应用程序:

<?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);
?>

此代码与名为 certificate.pem 的证书文件一起存储在我的服务器上。

自从一个月以来,我一直在使用此代码,没有任何问题。今天,我注意到我不再收到推送通知了。

PHP 错误日志显示如下:

[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

首先,我认为证书文件有问题。然后,我找到了这个:https://www.pushtry.com 网站。如果我插入设备令牌,上传 certificate.pem 文件,插入 Bundle ID 和一条消息,我将在我的应用程序中成功接收到推送消息。 (网站上有一个密码字段,但如果我不插入它,它也能正常工作。不知道,为什么。)所以这告诉我,certificate.pem 一定没问题。

你知道我做错了什么吗?为什么它不再起作用了?苹果改变了什么吗?

我终于解决了我的问题。大约一年前,Apple 对此进行了更改。不知道为什么今天才影响到我。

这是工作代码:

<?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;
?>

来源:https://gist.github.com/valfer/18e1052bd4b160fed86e6cbb426bb9fc