ApnsPHP:推送通知在开发中工作但不在生产中

时间:2013-09-26 15:04:17

标签: php ios apple-push-notifications apns-php

是的:这个问题有很多重复,但没有一个答案有帮助。

我关注这个伟大的tutorial by Ali Hafizji on using APNS service for push notifications

开发模式中测试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

Bang,调用发送推送通知的php脚本返回HTML状态代码500。

生成模式当然修改了$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

尝试通过ssl://gateway.push.apple.com:2195连接telnet只是为了确保:连接正常。

很明显:这是证书问题。

1 个答案:

答案 0 :(得分:7)

似乎aps_production.cer不应该像aps_development.cer

一样进行处理

RTM moment来了。

在钥匙串中下载并安装证书(双击aps_production.cer

从Keychain Access导出.p12版本的aps_production证书(此处也设置了密码)。

使用此命令将其转换为.pem格式(您必须在此处输入密码):

openssl pkcs12 -in aps_production.p12 -out final_aps_production.pem -nodes

voilà - 一切都开始了,我再次成为一个快乐的露营者。

Jeremy有很多关于如何出口证书和教程的类似教程的指示。键here on SO