苹果推送通知 - PHP - SSL操作失败,code 1 [英] Apple Push Notification - PHP - SSL operation failed with code 1

查看:1075
本文介绍了苹果推送通知 - PHP - SSL操作失败,code 1的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在过去的几天里,我们正在使用插座时,连接到服务器的APN我们的生产服务器上遇到PHP一些奇怪的行为。

For the last few days, we are experiencing some strange behaviour with PHP when using sockets to connect to APN servers on our production server.

有关大部分的时间,有效载荷被推动而没有任何错误,并在客户端接收该通知。但是,在一些情况下,我们开始接收一个PHP错误(即使我们收到一个错误,有时会通知推)。当我们开始看到这个错误,它继续了几个小时后消失和PHP继续工作就像什么都没有发生。

For most of the times, the payload is pushed without any errors and the client receives the notification. However on some cases we start receiving a PHP error (even though we are receiving an error, sometimes the notification is pushed). When we start to see this error, it continues for hours then disappears and PHP continues to work like nothing has happened.

另一个奇怪的是,从shell中运行相同的PHP code产生任何没有错误。从网页(nginx的/ PHP-FPM)不运行它......在外壳和网络运行PHP具有相同的配置和共享相同的php.ini。唯一不同的是网络上的php-fpm的运行。

Another strange thing is that, running the same PHP code from shell produces no errors whatsoever. Running it from web (nginx / php-fpm) does... PHP running on shell and web have the same configuration and share the same php.ini. The only difference is web is running on php-fpm.

另外,我们没有任何错误临时服务器在同一code +证书运行。生产服务器是分段服务器的副本,所以每一个配置是一样的。

Also, the same code + certificate runs on our staging server without any errors. Production server is a copy of the staging server, so every configuration is same.

我们能够找到一些答案,什么可能导致这个错误,包括来自stackoverflow.com答案,但我们没能找到一个解决方案或解决它。

We were able to find a few answers to what might be causing this error, including answers from stackoverflow.com, but we were not able to find a solution or solve it.

通知给苹果的服务器发送一个接一个,而不是作为一个包。但我们不会做太多的连接(每天大约有1,000)。没有排队系统。

Notifications to Apple servers are sent one by one, and not as a bundle. But we are not making too many connections (a thousand a day maybe). There is no queue system.

因此​​,简而言之


  • 我们有时会收到一个PHP的错误,而把我们的通知,但并非总是如此。

  • 通过相同的PHP从外壳发送通知不会产生任何错误

  • 从临时服务器不会产生任何错误
  • 发送通知

我们尝试了这些


  • 重新创建证书和密钥

  • 重新创建PEM文件

  • 更改SSL://到的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/"

在code连接,并从PHP发送有效载荷实际上是一个类的一部分,这部分是什么使连接,并发送有效载荷:

The code connecting and sending the payload from the php is actually part of a class, this part is what makes the connection and sends the 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是出现在错误信息283行

  • 我们不使用沙盒(SSLv3的://gateway.push.apple.com:2195)

  • PHP版本是5.3.15

  • 这是一个PHP或OpenSSL错误,我们不知道的?任何想法什么,在哪里检查?
    苹果公司是否有一个网站,我们可以检查APN网络的当前健康?

    Is this a PHP or OpenSSL bug that we don't know of? Any ideas what and where to check? Does Apple have a site where we can check the current health of the APN network?

    任何帮助是极大AP preciated ...
    谢谢

    Any help is greatly appreciated... Thanks

    推荐答案

    看看这个code发送多个消息

    Check out this code to send multiple messages

    $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.");
    }
    

    这篇关于苹果推送通知 - PHP - SSL操作失败,code 1的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆