Apple Push Notification - PHP - Error de operación SSL con el código 1
Durante los últimos días, estamos experimentando un extraño comportamiento con PHP cuando usamos sockets para conectarse a los servidores APN en nuestro servidor de producción.
La mayoría de las veces, la carga útil se envía sin ningún error y el cliente recibe la notificación. Sin embargo, en algunos casos, comenzamos a recibir un error de PHP (a pesar de que estamos recibiendo un error, a veces se envía una notificación). Cuando comenzamos a ver este error, continúa durante horas y luego desaparece y PHP continúa funcionando como si nada hubiera sucedido.
Otra cosa extraña es que, ejecutar el mismo código PHP desde shell no produce ningún error. Ejecutarlo desde la web (nginx / php-fpm) hace ... PHP ejecutándose en shell y web tienen la misma configuración y comparten el mismo php.ini. La única diferencia es que la web se ejecuta en php-fpm.
Además, el mismo código + certificado se ejecuta en nuestro servidor de ensayo sin ningún error. El servidor de producción es una copia del servidor de transferencia, por lo que cada configuración es la misma.
Pudimos encontrar algunas respuestas a lo que podría estar causando este error, incluidas las respuestas de stackoverflow.com, pero no pudimos encontrar una solución o resolverla.
Las notificaciones a los servidores de Apple se envían una por una, y no como un paquete. Pero no estamos haciendo demasiadas conexiones (tal vez mil al día). No hay sistema de colas.
Así que, en definitiva
A veces recibimos un error de PHP al enviar nuestras notificaciones, pero no siempre.El envío de notificaciones desde shell a través de PHP mismo no produce ningún errorEl envío de notificaciones desde el servidor de ensayo no produce ningún errorProbamos estos
Recreando el certificado y la claveRecreando el archivo PEMCambiar ssl: // a sslv3: //Usando stream_socket_clientUtilizando fsockopenCambiar / eliminar contraseña de certificadoEl error es:
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/"
El código que conecta y envía la carga útil desde el php es en realidad parte de una clase, esta parte es la que establece la conexión y envía la carga útil:
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 es la línea 283 que aparece en el mensaje de errorNo estamos utilizando el sandbox (sslv3: //gateway.push.apple.com: 2195)La versión de PHP es 5.3.15¿Es este un error de PHP o OpenSSL que no conocemos? ¿Alguna idea de qué y dónde revisar? ¿Tiene Apple un sitio donde podamos verificar el estado actual de la red APN?
Cualquier ayuda es muy apreciada, gracias