推送通知发送成功,但设备没有收到(偶尔) [英] Push notification is successfully sent, but the device does not receive (occasionally)

查看:50
本文介绍了推送通知发送成功,但设备没有收到(偶尔)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

自昨天以来,我一直遇到一些设备无法收到推送通知的问题.证书/设备令牌似乎是正确的,因为该设备曾经成功接收推送通知,直到昨天.

I have been having a problem where some devices will not receive a push notification, since yesterday. The certificate / device token seem to be correct, since the device used to successfully receive push notifications until yesterday.

在服务器端,没有错误或连接拒绝,并且推送通知好像每次都成功发送.

On the server-side, there are no errors or connection refusals, and the push notification seems to be successfully sent every time.

但是,仍然有很多情况下设备没有正确接收推送.

But still, there are many occasions where the device does not correctly receive the push.

一些周边信息:

  • 我正在生产环境中执行此操作.
  • 服务器端没有错误/连接拒绝
  • 我每次都发送完全相同的 JSON.
  • 自昨天以来,我们的 2 台设备根本没有收到推送通知
  • 我们的 1 台设备接收推送通知的成功率(约 70%)低于昨天
  • 即使现在,我们的 1~2 台设备仍能成功接收推送通知.
  • 直到昨天,上述所有设备都能够在生产环境中正确接收推送通知.

推送成功时和设备未收到时服务器端结果没有区别...因此,几乎不可能找出问题所在.

这是我使用的服务器端 PHP 代码:

This is the server-side PHP code I am using:

        $ctx = stream_context_create();
        stream_context_set_option($ctx, 'ssl', 'local_cert', $this->apnsData[$development]['certificate']);
        $fp = stream_socket_client($this->apnsData[$development]['ssl'], $error, $errorString, 100, (STREAM_CLIENT_C ONNECT|STREAM_CLIENT_PERSISTENT), $ctx);

        if(!$fp){
                $this->_pushFailed($pid);
                $this->_triggerError("Failed to connect to APNS: {$error} {$errorString}.");
        }
        else {
                $msg = chr(0).pack("n",32).pack('H*',$token).pack("n",strlen($message)).$message;
                $fwrite = fwrite($fp, $msg);
                if(!$fwrite) {
                        error_log("[APNS] push failed...");
                        $this->_pushFailed($pid);
                        $this->_triggerError("Failed writing to stream.", E_USER_ERROR);
                }
                else {
                        error_log("[APNS] push successful! ::: $token -> $message ($fwrite bytes)");
                }
        }
        fclose($fp);

日志告诉我推送成功(为了隐私而删掉令牌):

The log tells me that the push was successful (Cutting out the token for privacy) :

[Wed Dec 12 11:42:00 2012] [error] [client 10.161.6.177] [APNS] push successful! ::: aa4f******44 -> {"aps":{"alert":{"body":"\\u300casdfasdf\\u300d","action-loc-key":"OK"},"badge":4,"sound":"chime"}} (134 bytes)

我该如何解决这个问题?

How do I solve this?

推荐答案

我自己解决了这个问题,所以我会发布一个答案.

Solved this by myself, so I'll be posting an answer.

我收到的建议是不建议为每条消息打开和关闭套接字,如 Apple 官方文档中所述:

I've received advice that opening and closing the socket for every single message is not recommended, as noted in Apple's official documents:

您还应该在多个通知中保留与 APNs 的连接.APNs 可能会将快速重复建立和断开的连接视为拒绝服务攻击.发生错误时,APNs 会关闭发生错误的连接."

"You should also retain connections with APNs across multiple notifications. APNs may consider connections that are rapidly and repeatedly established and torn down as a denial-of-service attack. Upon error, APNs closes the connection on which the error occurred."

我修复了我的架构,以便在多个 APNS 调用中保持连接,现在它可以正常工作了.我创建了一个基于 apns-php (https://code.google.com/p/apns-php/).

I fixed my architecture so that the connection is retained throughout multiple APNS calls, and now it is working without any problem. I created a queueing system based on apns-php (https://code.google.com/p/apns-php/).

这是我的代码,供任何需要它的人使用:

Here is my code, for anyone who needs it:

https://github.com/ashiina/APNS-QueueServer

这篇关于推送通知发送成功,但设备没有收到(偶尔)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆