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

Rok*_*arc 4 php apple-push-notifications ios apns-php

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

我正在按照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
Run Code Online (Sandbox Code Playgroud)

并且(在服务器上使用ApnsPHP)我可以使用此配置成功发送推送通知:

...
$push = new ApnsPHP_Push(ApnsPHP_Abstract::ENVIRONMENT_SANDBOX,'final_aps_development.pem');
$push->setRootCertificationAuthority('entrust_root_certification_authority.pem');
$push->setProviderCertificatePassphrase('mypassword');
...
Run Code Online (Sandbox Code Playgroud)

旁注:我从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配置实用程序将其安装在设备上.

我遵循相同的程序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');
...
Run Code Online (Sandbox Code Playgroud)

快速查看/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  ....
Run Code Online (Sandbox Code Playgroud)

谷歌搜索(有很多人有这个问题)证明没有结果.

许多不同的建议,甚至如此眩晕,以至于将持有证书的目录的文件权限更改为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
        ))); 
Run Code Online (Sandbox Code Playgroud)

那个讨厌的东西ApnsPHP_Exception没有消失.

当然,我还确保当我测试生产模式时,正确的设备APNS令牌 - 设备APNS令牌在调试和生产模式下是不一样的 - 被使用.

无论如何:令牌不是问题,因为我的通知发送脚本甚至无法连接ssl://gateway.push.apple.com:2195.

试图连接ssl://gateway.push.apple.com:2195通过telnet公正,以确保:连接被罚款.

很明显:这是一个证书问题.

Rok*_*arc 7

似乎aps_production.cer不应该以同样的方式进行处理aps_development.cer

这是RTM时刻.

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

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

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

openssl pkcs12 -in aps_production.p12 -out final_aps_production.pem -nodes
Run Code Online (Sandbox Code Playgroud)

而瞧 -一切都开始工作,我又是一个快乐的人.

关于如何在SO上导出证书和密钥,Jeremy有很好的教程指示.

  • 我可以吻你 (4认同)
  • 哈!非常感谢这种直截了当的方法!对于任何苦苦挣扎的人来说,只需忘记在线教程并将该过程视为几分钟.如果你在这里,你的问题显然只是创建.PEM文件,而且所有的教程都让它看起来像是必须涉及多个文件和命令.只需将分发推送aps_production.cer导入Keychain Access,在Keychain Access中找到它并展开它,以便您看到私钥,选择"导出2个项目"作为.p12文件.上传到服务器,SSH并在上面运行openssl命令 - 完成!美丽. (2认同)