是的:这个问题有很多重复,但是没有一个答案能够解决我的问题。
我正在按照 Ali Hafizji 的 教程 学习如何使用 APNS 服务进行推送通知。
在开发模式下测试 APNS:
- 下载
aps_development.cer
- 导出证书的私钥 (
aps_development_key.p12
)
然后,我使用以下命令(在终端中)将两者合并:
openssl x509 -in aps_development.cer -inform der -out aps_development.pem
openssl pkcs12 -nocerts -out aps_development_key.pem -in aps_development.p12
cat aps_development.pem aps_development_key.pem > final_aps_development.pem
使用服务器上的ApnsPHP,我可以成功地使用以下配置发送推送通知:
...
$push = new ApnsPHP_Push(ApnsPHP_Abstract::ENVIRONMENT_SANDBOX,'final_aps_development.pem');
$push->setRootCertificationAuthority('entrust_root_certification_authority.pem');
$push->setProviderCertificatePassphrase('mypassword');
...
一个小提示:我从https://github.com/jonathanrcarter/push2press中获取了entrust_root_certification_authority.pem文件,但正确的地址可能是https://www.entrust.net/downloads/binary/entrust_2048_ca.cer(它们本质上是相同的)。
在此情况下,应用程序在调试模式下运行(在设备上通过XCode运行),一切正常。
在生产模式下测试APNS:
为了在生产模式下测试APNS,我为AdHoc分发存档了应用程序,并使用iPhone Configuration Utility将其安装到设备上。
对于aps_production.cer,我遵循了相同的过程以生成final_aps_production.pem文件。
结果,用于发送推送通知的PHP脚本返回了500 HTML状态码。
当然,$push生成已针对生产模式进行修改。
...
$push = new ApnsPHP_Push(ApnsPHP_Abstract::ENVIRONMENT_PRODUCTION,'final_aps_production.pem');
$push->setRootCertificationAuthority('entrust_root_certification_authority.pem');
$push->setProviderCertificatePassphrase('mypassword');
...
快速查看 /var/log/apache2/error.log
文件,可以发现问题所在:
PHP Fatal error: Uncaught exception 'ApnsPHP_Exception' with message 'Unable to connect to 'ssl://gateway.push.apple.com:2195': (0)' in /var/www/gettapro/mobile/ApnsPHP/Abstract.php:398\nStack trace:\n#0 /var/www/gettapro/mobile/ApnsPHP/Abstract.php(334): ApnsPHP_Abstract->_connect()\n#1 ....
搜索解决问题的方法,但并没有找到有效的结果(许多人都有此问题)。有许多不同的建议,甚至有些奇怪,比如将持有证书的目录的文件权限更改为775……但这些建议都没有对我起作用。我还尝试了在"ApnsPHP/Abstract.php"上进行更改(参见:https://github.com/duccio/ApnsPHP/issues/29), 但是也没有成功。
$streamContext = stream_context_create(array('ssl' => array(
//'verify_peer' => isset($this->_sRootCertificationAuthorityFile),
'cafile' => $this->_sRootCertificationAuthorityFile,
'local_cert' => $this->_sProviderCertificateFile
)));
这讨厌的ApnsPHP_Exception
问题并没有消失。
当然,在测试生产模式时,我也确保使用了正确的设备APNS令牌 - 在调试和生产模式下,设备APNS令牌不同。
无论如何:令牌不可能是问题,因为我的通知发送脚本甚至无法连接到ssl://gateway.push.apple.com:2195
。
尝试通过telnet
连接ssl://gateway.push.apple.com:2195
只是为了确保:连接很好。
很明显:这是一个证书问题。