这个 php 脚本是不是仍可用于使用 APNs 发送测试推送通知? [基于证书的连接]

Posted

技术标签:

【中文标题】这个 php 脚本是不是仍可用于使用 APNs 发送测试推送通知? [基于证书的连接]【英文标题】:Can this php script still be used to send test push notifications using APNs? [Certificate Based Connection]这个 php 脚本是否仍可用于使用 APNs 发送测试推送通知? [基于证书的连接] 【发布时间】:2022-01-03 09:45:31 【问题描述】:

此脚本用于在 Apple 切换到 new APNs Provider API 之前向测试设备发送测试推送通知,我很惊讶更多人没有谈论它。

现在,当我从终端输入 php simplepush.php 运行脚本时,输出显示

虽然没有收到任何消息。

//simplepush.php

<?php

// Put your device token here (without spaces):
$deviceToken = 'EXAMPLETOKEN';
// Put your private key's passphrase here:
$passphrase = 'pushchat';
// Put your alert message here:
$message = 'Hello!';
////////////////////////////////////////////////////////////////////////////////
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'ck.pem');
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);
// Open a connection to the APNS server
$fp = stream_socket_client(
'ssl://api.sandbox.push.apple.com:443', $err,
$errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);
if (!$fp)
exit("Failed to connect: $err $errstr" . PHP_EOL);
echo 'Connected to APNS' . PHP_EOL;
// Create the payload body
$body['aps'] = array(
'alert' => $message,
'sound' => 'default'
);
// Encode the payload as JSON
$payload = json_encode($body);
// Build the binary notification
$msg = chr(0) . pack('n', 32) . pack('H*', $deviceToken) . pack('n',     strlen($payload)) . $payload;
// Send it to the server
$result = fwrite($fp, $msg, strlen($msg));
if (!$result)
echo 'Message not delivered' . PHP_EOL;
else
echo 'Message successfully delivered' . PHP_EOL;
// Close the connection to the server
fclose($fp);

自从 Apple 于去年 3 月做出转换以来,我已经:

    创建了一个新的Certificate Signing Request Registered a new App ID Established a Certificate-Based Connection to APNs Obtained a new Provider Certificate from Apple Installed the Certificate and Private Key Established Trust with APNs Sent Push Notifications Using Command-Line Tools

当我关注Sending Push Notifications Using Command-Line Tools 时,我能够收到测试通知。

curl -v --header 'apns-topic: com.your.site' --header apns-push-type: alert --cert aps.cer --cert-type DER --key PushChatKey.pem --key-type PEM --data '"aps":"alert":"Test"' --http2 https://api.sandbox.push.apple.com/3/device/DEVICETOKEN

自从苹果对新的 APNs Provider API 进行了更改后,是否仍然可以使用这个 php 脚本来发送测试推送通知?我知道 Apple 开发人员文档中提到了 required header request fields,但老实说,我不知道这些是从终端实现还是直接在脚本中实现。

【问题讨论】:

$result = fwrite($fp, $msg, strlen($msg)); 您那里的代码看起来很古老,与您链接的文档中描述的过程完全不同。这似乎不太可能是您需要自己编写的代码。肯定有具有此功能的库。 另外来自您链接到的文档:“自 2021 年 3 月 31 日起,APN 将不再支持旧的二进制协议。我们建议尽快从此页面更新到基于 HTTP/2 的 API 。” miken32提到,推荐使用http/2 API。有什么不使用图书馆的特殊理由吗?喜欢github.com/gepo/apns-http2 @PauloH。只是熟悉。这是 2013 年教程的第一部分,该教程在相同的证书和配置文件用于 API 之前发送测试通知,该 API 使用 ios 的 APNs 发送带有 UI 更新的用户消息。 【参考方案1】:

如果您的 curl 调用有效,为什么不将其转换为 PHP

例子:

$url = "https://api.sandbox.push.apple.com/3/device/DEVICETOKEN";
$ch = curl_init($url);

$data = json_encode(["aps" => ["alert" => "Test"]]);

curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data); // can be URL encoded string

$headers = array();
$headers[] = 'Apns-Topic: com.your.site';
$headers[] = 'Apns-Push-Type: ';
$headers[] = 'Content-Type: application/json';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) 
    echo 'Error:' . curl_error($ch);

curl_close($ch);

如果您需要知道如何在 PHP 中将证书与 CURL 一起使用,请查看 this answer

【讨论】:

$data = json_encode(["aps" =&gt; ["alert" =&gt; "Test"]]); 永远不要编写自己的 JSON。内容类型也应更改为 JSON。客户端证书在哪里? 和 HTTP 2.0 支持。 不知道他们的新 api,但是通过 OP 损坏的示例代码,旧 API 根本不使用 HTTP,它在 TLS 套接字上使用自己的自定义二进制协议:o 这非常罕见(并且可能是一个古老的设计决定) 您的内容类型标头是假的,应该是$headers[] = 'Content-Type: application/json'; 感谢 miken32 和 hanshenrik 我更新了我的答案。

以上是关于这个 php 脚本是不是仍可用于使用 APNs 发送测试推送通知? [基于证书的连接]的主要内容,如果未能解决你的问题,请参考以下文章

通过 PHP 到 APNS 的持久连接

PHP 代码如何将 APNS 设备令牌用于 Apple 推送通知?

带有 PHP 的 iOS 13 APNS

ASP.NET WebForms Authentication Logout, Cookie 仍可用于访问站点

APNs Provider API HTTP/2 使用 php,curl 导致发送的多个推送通知出错

iOS App处于后台/被杀死的状态仍可进行语言播报的实现方案