Notificação Push Apple - PHP - operação SSL falhou com o código 1
Nos últimos dias, estamos experimentando um comportamento estranho com o PHP ao usar soquetes para conectar-se a servidores APN em nosso servidor de produção.
Na maior parte do tempo, a carga é enviada sem erros e o cliente recebe a notificação. No entanto, em alguns casos, começamos a receber um erro do PHP (apesar de estarmos recebendo um erro, às vezes a notificação é enviada). Quando começamos a ver esse erro, ele continua por horas e depois desaparece e o PHP continua a funcionar como se nada tivesse acontecido.
Outra coisa estranha é que, executando o mesmo código PHP do shell não produz nenhum erro. Executá-lo da web (nginx / php-fpm) faz ... PHP rodando em shell e web tem a mesma configuração e compartilham o mesmo php.ini. A única diferença é que a web está rodando em php-fpm.
Além disso, o mesmo código + certificado é executado em nosso servidor de teste sem erros. O servidor de produção é uma cópia do servidor de temporariedade, portanto, toda configuração é a mesma.
Conseguimos encontrar algumas respostas para o que pode estar causando esse erro, incluindo respostas de stackoverflow.com, mas não conseguimos encontrar uma solução ou resolvê-la.
As notificações aos servidores da Apple são enviadas uma a uma e não como um pacote. Mas não estamos fazendo muitas conexões (mil por dia talvez). Não há sistema de fila.
Então, em resumo
Às vezes recebemos um erro de PHP ao enviar nossas notificações, mas nem sempre.Enviar notificações do shell via mesmo PHP não produz errosEnviar notificações do servidor de temporariedade não produz errosNós tentamos estes
Recriando o certificado e a chaveRecriando o arquivo PEMAlterando ssl: // para sslv3: //Usando stream_socket_clientUsando fsockopenAlterando / removendo a senha do certificadoO erro é:
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/"
O código conectando e enviando o payload do php é na verdade parte de uma classe, esta parte é o que faz a conexão e envia o payload:
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 é a 283ª linha que aparece na mensagem de erroNós não estamos usando o sandbox (sslv3: //gateway.push.apple.com: 2195)Versão do PHP é 5.3.15Isso é um bug PHP ou OpenSSL que não conhecemos? Alguma idéia do que e onde verificar? A Apple tem um site onde podemos verificar a saúde atual da rede APN?
Qualquer ajuda é muito apreciada, obrigado