Apple Push Notification – Ошибка PHP-SSL с кодом 1

В течение последних нескольких дней мы сталкиваемся с каким-то странным поведением с PHP при использовании сокетов для подключения к серверам APN на нашем производственном сервере.

В большинстве случаев полезная нагрузка выгружается без каких-либо ошибок, и клиент получает уведомление. Однако в некоторых случаях мы начинаем получать ошибку PHP (даже при том, что мы получаем ошибку, иногда уведомление нажимается). Когда мы начинаем видеть эту ошибку, она продолжается в течение нескольких часов, а затем исчезает, и PHP продолжает работать, как ничего не случилось.

Еще одна странная вещь: запуск одного и того же PHP-кода из оболочки не вызывает никаких ошибок. Запуск его из Интернета (nginx / php-fpm) делает … PHP, работающий на оболочке и в Интернете, имеет одинаковую конфигурацию и использует один и тот же php.ini. Единственное различие заключается в том, что web работает на php-fpm.

Кроме того, тот же код + сертификат запускается на нашем промежуточном сервере без каких-либо ошибок. Сервер производства – это копия промежуточного сервера, поэтому каждая конфигурация такая же.

Нам удалось найти несколько ответов на то, что может вызвать эту ошибку, включая ответы от stackoverflow.com, но мы не смогли найти решение или решить его.

Уведомления на серверах Apple отправляются один за другим, а не как пакет. Но мы не делаем слишком много связей (может быть, тысяча в день). Система очередей отсутствует.

Итак, короче

  • Мы иногда получаем ошибку PHP при отправке наших уведомлений, но не всегда.
  • Отправка уведомлений из оболочки через один и тот же PHP не приводит к ошибкам
  • Отправка уведомлений с промежуточного сервера не приводит к ошибкам

Мы пробовали эти

  • Воссоздание сертификата и ключа
  • Воспроизведение файла PEM
  • Изменение ssl: // to sslv3: //
  • Использование stream_socket_client
  • Использование fsockopen
  • Изменение / удаление пароля сертификата

Ошибка:

2012/08/28 12:18:09 [error] 4282#0: *225858 FastCGI sent in stderr: "PHP message: PHP Warning: fwrite() [<a href='function.fwrite'>function.fwrite</a>]: SSL operation failed with code 1. OpenSSL Error messages: error:1409F07F:SSL routines:func(159):reason(127) in /usr/local/nginx/html/play/classes/PushNotification.php on line 283" while reading response header from upstream, client: 94.---.---.---, server: play.--------.com, request: "POST /game_request_random.php HTTP/1.1", upstream: "fastcgi://unix:/var/run/phpfpm.sock:", host: "play.--------.com", referrer: "http://--------.com/" 

Код, соединяющий и отправляющий полезную нагрузку из php, фактически является частью класса, эта часть делает соединение и отправляет полезную нагрузку:

  private function ConnectAndSend ( $msg = false ) { $ctx = stream_context_create(); stream_context_set_option( $ctx, 'ssl', 'local_cert', $this->certificate ); stream_context_set_option( $ctx, 'ssl', 'passphrase', $this->certificatepass ); // Open a connection to the APNS server $fp = stream_socket_client( APN_SERVER, $err, $errstr, 60, STREAM_CLIENT_CONNECT | STREAM_CLIENT_PERSISTENT, $ctx ); if ( !$fp ) { errorlog( "Push notification error : $err $errstr" ); $this->error = "$err $errstr"; return; } // Build the notification if ( !$msg ) { $msg = chr( 0 ) . pack( 'n', 32 ) . pack( 'H*', $this->devicetoken ) . pack( 'n', strlen( $this->payload ) ) . $this->payload; } // Send it to the server if ( !($result = fwrite( $fp, $msg, strlen( $msg ) )) ) { // Could not send $this->error = 'Notification could not be send'; errorlog( "Push notification error : {$this->error}" ); } else { // Notification sent $this->error = false; errorlog( "Push notification sent" ); } fclose($fp); // Reset the content $this->devicetoken = false; $this->message = false; $this->command = false; $this->badge = 0; $this->payload = false; $this->sound = false; } 
  • stream_socket_connection – это 283-я строка, появляющаяся в сообщении об ошибке
  • Мы не используем песочницу (sslv3: //gateway.push.apple.com: 2195)
  • Версия PHP – 5.3.15

Является ли это ошибкой PHP или OpenSSL, о которой мы не знаем? Любые идеи, что и где проверять? У Apple есть сайт, на котором мы можем проверить текущее состояние сети APN?

Любая помощь очень ценится … Спасибо

Related of "Apple Push Notification – Ошибка PHP-SSL с кодом 1"

Проверьте этот код для отправки нескольких сообщений

 $i = 0; while($res = mysql_fetch_array( $result )) { $deviceTokens[$i] = $res['token']; $i++; } // APNs Push testen auf Token //$deviceToken = $token; // Hier das Device-Token angeben, ist 64-stellig // Payload erstellen und JSON codieren $message = $_POST['message']; $message = utf8_encode($message); $payload['aps'] = array('alert' => 'Neuer Artikel in Aktuelles', 'badge' => +1, 'sound' => 'default'); if (trim($message) != '') { $payload['aps'] = array('alert' => "$message", 'badge' => 1, 'sound' => 'default'); } $payload = json_encode($payload); //Development: $apnsHost = 'gateway.sandbox.push.apple.com'; $apnsHost = 'gateway.push.apple.com'; $apnsPort = 2195; //Development: $apnsCert = 'apsDevBundle.pem'; $apnsCert = 'apns-dev.pem'; // Stream erstellen $streamContext = stream_context_create(); stream_context_set_option($streamContext, 'ssl', 'local_cert', $apnsCert); $apns = stream_socket_client('ssl://' . $apnsHost . ':' . $apnsPort, $error, $errorString, 2, STREAM_CLIENT_CONNECT, $streamContext); if ($error==0) { for($i = 0; $i<count($deviceTokens); $i++) { // Build the binary notification $apnsMessage = chr(0) . chr(0) . chr(32) . pack('H*', str_replace(' ', '', $deviceTokens[$i])) . chr(0) . chr(strlen($payload)) . $payload; fwrite($apns, $apnsMessage); } // Verbindung schliessen fclose($apns); } else { var_dump($error); var_dump($errorString); die("Fehler aufgetreten."); }