Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.
  • 2 of our devices are not receiving the push notification AT ALL since yesterday
  • 1 of our device receives push notifications at a lower success rate (about 70%) than yesterday
  • 1~2 of our devices still receive push notifications successfully even now.
  • 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:

        $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?

like image 814
ashiina Avatar asked Dec 12 '12 04:12

ashiina


2 Answers

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:

"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."

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

like image 75
ashiina Avatar answered Oct 24 '22 05:10

ashiina


First check if your device is jailbreak then it will not support PushNotification. For that you have to download SAMPref app from Cydia and open that app then your device is supporting push notification. You can test your device for push notification using iPusher app from app store. 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

like image 31
Tushar - iOS developer Avatar answered Oct 24 '22 05:10

Tushar - iOS developer