简体   繁体   English

推送通知已成功发送,但设备未收到(偶尔)

[英]Push notification is successfully sent, but the device does not receive (occasionally)

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. 但是,在很多情况下,设备无法正确接收推送。

Some surrounding information: 一些周边信息:

  • I am doing this on the production environment. 我在生产环境中这样做。
  • No errors / connection refusals on the server-side 服务器端没有错误/连接拒绝
  • I am sending the exactly same JSON everytime. 我每次都发送完全相同的JSON。
  • 2 of our devices are not receiving the push notification AT ALL since yesterday 自昨天起,我们的2台设备未收到AT ALL的推送通知
  • 1 of our device receives push notifications at a lower success rate (about 70%) than yesterday 我们的设备中有一个接收推送通知的成功率(约70%)低于昨天
  • 1~2 of our devices still receive push notifications successfully even now. 即使是现在,我们仍有1到2台设备成功接收推送通知。
  • All of the above devices were able to receive push notifications properly on the production environment until yesterday. 所有上述设备都能够在生产环境中正确接收推送通知,直到昨天。

There is no difference in the server-side result for when the push is successful, and when the device doesn't receive it... Therefore it is virtually impossible to identify the problem. 当推送成功时,以及当设备没有收到时,服务器端结果没有区别......因此几乎不可能识别问题。

This is the server-side PHP code I am using: 这是我使用的服务器端PHP代码:

        $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. 我自己解决了这个问题,所以我会发布一个答案。

I've received advice that opening and closing the socket for every single message is not recommended, as noted in Apple's official documents: 我已收到建议,建议不要为每条消息打开和关闭套接字,如Apple官方文档中所述:

"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." “您还应该在多个通知中保留与APN的连接.APN可能会考虑快速重复建立的连接,并将其拆除为拒绝服务攻击。一旦出现错误,APN将关闭发生错误的连接。”

I fixed my architecture so that the connection is retained throughout multiple APNS calls, and now it is working without any problem. 我修复了我的架构,以便在多个APNS调用中保留连接,现在它正在运行,没有任何问题。 I created a queueing system based on apns-php ( https://code.google.com/p/apns-php/ ). 我创建了一个基于apns-php( https://code.google.com/p/apns-php/ )的排队系统。

Here is my code, for anyone who needs it: 这是我的代码,适合任何需要它的人:

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

First check if your device is jailbreak then it will not support PushNotification. 首先检查您的设备是否越狱,然后它将不支持PushNotification。 For that you have to download SAMPref app from Cydia and open that app then your device is supporting push notification. 为此,您必须从Cydia下载SAMPref应用程序并打开该应用程序,然后您的设备支持推送通知。 You can test your device for push notification using iPusher app from app store. 您可以使用应用程序商店中的iPusher应用程序测试设备的推送通知。 if you receive push notification then your device is supported. 如果您收到推送通知,则支持您的设备。

After that first check your app is signed using proper push notification enabled certificate? 在第一次检查之后,您的应用是否已使用正确的推送通知启用证书进

Thank 谢谢

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM