Push-уведомление успешно отправлено, но устройство не получает (иногда)

У меня возникла проблема, когда некоторые устройства не получают push-уведомления со вчерашнего дня. Символ сертификата / устройства кажется правильным, поскольку устройство, используемое для успешного получения push-уведомлений до вчерашнего дня.

На стороне сервера нет ошибок или отказов соединений, и push-уведомление, кажется, успешно отправляется каждый раз.

Но все же, есть много случаев, когда устройство неправильно получает нажатие.

Некоторая окружающая информация:

  • Я делаю это в производственной среде.
  • Нет ошибок / отказов подключения на стороне сервера
  • Я отправляю точно такой же JSON каждый раз.
  • 2 из наших устройств не получают push-уведомление AT ALL со вчерашнего дня
  • 1 нашего устройства получает push-уведомления при более низком уровне успеха (около 70%), чем вчера
  • 1 ~ 2 наших устройств до сих пор получают push-уведомления даже сейчас.
  • Все вышеперечисленные устройства смогли получать push-уведомления должным образом в производственной среде до вчерашнего дня.

Нет никакой разницы в результатах на стороне сервера, когда успешное нажатие и когда устройство не получает его … Поэтому практически невозможно идентифицировать проблему.

Это серверный 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); 

Журнал сообщает мне, что нажатие было успешным (вырезание токена для конфиденциальности):

 [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) 

Как я могу это решить?

Решил это сам, поэтому я отправлю ответ.

Я получил совет, что открытие и закрытие сокета для каждого отдельного сообщения не рекомендуется, как указано в официальных документах Apple:

«Вы также должны сохранять соединения с APN через несколько уведомлений. APN могут рассматривать соединения, которые быстро и неоднократно устанавливаются и сбрасываются как атака отказа в обслуживании. По ошибке APN закрывает соединение, в котором произошла ошибка».

Я исправил свою архитектуру, чтобы соединение сохранялось во многих вызовах APNS, и теперь оно работает без каких-либо проблем. Я создал систему очередей на основе apns-php ( https://code.google.com/p/apns-php/ ).

Вот мой код для всех, кто в этом нуждается:

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

Сначала проверьте, является ли ваше устройство джейлбрейком, тогда оно не будет поддерживать PushNotification. Для этого вам нужно загрузить приложение SAMPref из Cydia и открыть это приложение, после чего ваше устройство поддерживает push-уведомление. Вы можете протестировать устройство для push-уведомления с помощью приложения iPusher из магазина приложений. если вы получаете push-уведомление, ваше устройство будет поддерживаться.

После этого сначала проверьте, что ваше приложение подписано с помощью соответствующего сертификата с поддержкой push-уведомлений?

спасибо