ios推送通知在服务器上不起作用


ios Push Notification not working on the server

我在本地机器上测试了推送通知,它运行得很好。然后,我用相同的证书(".pem"文件)将我的文件上传到真实的服务器,并确保端口2195和2196是打开的。

我测试过:

telnet gateway.sandbox.push.apple.com 2195

它正在工作。。。

root@server ~ # telnet gateway.sandbox.push.apple.com 2195
Trying 17.149.34.54...
Connected to gateway.sandbox.push.apple.com.
Escape character is '^]'.

但当我从php脚本进行测试时,它会返回:

警告:stream_socket_client()[function.stream socket-client]:无法连接到ssl://gateway.sandbox.push.apple.com:2195(连接超时)

警告:stream_socket_client()[function.stream socket-client]:无法连接到ssl://feedback.sandbox.push.apple.com:2196

有什么建议吗?


这是php代码:

$ctx = stream_context_create(); 
stream_context_set_option($ctx, 'ssl', 'local_cert',
   "path/to/certificate"); 
$fp = stream_socket_client("ssl://gateway.push.apple.com:2195",
   $error, $errorString, 100,
   (STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT), $ctx);

此代码将正常工作:

 $device = 'sdfsdfsfsdffsd';
$payload['aps'] = array('alert' => 'Hello I am testing the server code ....', 'badge' => 1, 'sound' => 'default');
$payload = json_encode($payload);
$options = array('ssl' => array(
  'local_cert' =>'ck.pem',
  'passphrase' => 'abc123'
));

$streamContext = stream_context_create();
stream_context_set_option($streamContext, $options);
$apns = stream_socket_client('ssl://gateway.sandbox.push.apple.com:2195', $error, $errorString, 60, STREAM_CLIENT_CONNECT, $streamContext);
$apnsMessage = chr(0) . chr(0) . chr(32) . pack('H*', str_replace(' ', '', $device)) . chr(0) . chr(strlen($payload)) . $payload;
fwrite($apns, $apnsMessage);
fclose($apns);

只检查pem文件路径,并且端口处于打开状态。

我也遇到了同样的问题,无法连接到。。。(连接超时)'。我可以从家用机器连接,但不能从主机服务器连接。

在我的案例中,端口2195和2196并不是简单地从托管服务器打开的。我不得不联系技术支持来打开这些端口。Ping可能有效,因为它使用不同的端口号。因此,请联系您的托管服务公司,以确保这些端口是开放的。

祝你好运,

Kaz

stream_socket_client函数中,您不应该传递证书路径,而应该传递APNS url。

此方法打开连接并返回:

public function connect(){
        $streamContext = stream_context_create();
        stream_context_set_option($streamContext, 'ssl', 'local_cert', '/your/cert/path');
        $apns = stream_socket_client('use.apns.url.here', $error, $errorString, 9, STREAM_CLIENT_CONNECT, $streamContext);
        if (!$apns){
            $this->logger->error("Failed to connect to APNS: {$error} {$errorString}.");
        }
        return $apns;
    }

一旦你建立了你的apns消息,你可以使用以下推送它

fwrite($apns, $apnsMessage);

您可以遵循本教程http://goo.gl/9Q0u如果您的目标是实现您自己的推送通知API。

还有现有的php库:

  • http://code.google.com/p/apns-php/
  • http://www.easyapns.com/

还有一个非常好的Java库(我目前使用它进行大规模推送):

  • https://github.com/notnoop/java-apns

您必须设置防火墙以允许所有17.0.0.0/8块(它都属于Apple!)。检查此答案

根据苹果公司的说法:

APN服务器使用负载平衡,因此您的设备不会总是连接到同一个公共IP地址进行通知。最好允许访问分配给苹果的整个17.0.0.0/8地址块上的这些端口。

如果你正在使用CSF防火墙(像我一样),我建议在CSF.allow文件中添加这一行:

tcp|out|d=2195|d=17.0.0.0/8

使用它而不仅仅是"17.0.0.0/8"将只允许到苹果的外接连接,特别是到2195端口的外接。美国国家安全局不会喜欢它,但它更精确、更安全!)