1

我试图实现APNS(推送通知)。 我已经创建了证书等等。一切都像iv'e一样被创造了许多次。 但我不能从苹果APNS服务器得到一个错误,似乎一切正常,但我仍然没有得到任何推动设备。 这是我用来制作魔法的PHP代码:) 我确保在主机中打开PORTS。推送通知(iOS)未收回/用PHP代码发送

基本上我从数据库获取用户令牌并发送默认声音的推送文本。

有人可以请看看,并告诉我,如果你可以看到这段代码中的任何问题或让我知道我怎么能从APNS服务器获得过程/响应的真实结果?

<?php 
    error_reporting(0); 
    header("Content-type: application/json; charset=utf-8"); 
    include "dbconn.php"; 
    $data = array(); 
    $json= array(); 
    $users = array(); 

    $opponent_id = $_REQUEST['opponent_id']; 
    $sender_id = $_REQUEST['sender_id']; 
    $message = $_REQUEST['message']; 

    $sql = "SELECT * FROM `registration` WHERE `chat_id` ='$opponent_id'"; 

    $result = mysql_query($sql); 

    if (!$result) { 
     echo "Could not successfully run query ($sql) from DB: " . mysql_error(); 
     exit; 
    } 

    if (mysql_num_rows($result) == 0) { 
     echo "No rows found, nothing to print so am exiting"; 
     exit; 
    } 

    while ($row = mysql_fetch_assoc($result)) { 
      $token = $row['token']; 
    } 

    echo "\n$token"; 

    $passphrase = 'certificate_password'; 

    $ctx = stream_context_create(); 
    stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase); 
    //stream_context_set_option($ctx, 'ssl', 'local_cert','push/some_prod_certificate.pem'); 
    stream_context_set_option($ctx, 'ssl', 'local_cert','push/some_dev_certificate.pem'); 
    stream_context_set_option($ctx, 'ssl', 'cafile', 'push/entrust_root_certification_authority.pem'); 

    # Open a connection to the APNS server 
    $fp = stream_socket_client(//'ssl://gateway.push.apple.com:2195', $err, 
           'ssl://gateway.sandbox.push.apple.com:2195', $err, 
           $errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx); 


    if (!$fp){ 
     echo "Error: ".$err; 
     exit; 
    } 

    echo "\n".'Connected to APNS Push Notification' . PHP_EOL; 

    $body['aps'] = array(
         'alert' => $message, 
         'sound' => 'default' 
         ); 

    $payload = json_encode($body); 
    echo "\n$payload"; 

    // Build the binary notification 
    $msg = chr(0) . pack('n', 32) . pack('H*', $token) . pack('n', strlen($payload)) . $payload; 

    // Send it to the server 
    $result = fwrite($fp, $msg, strlen($msg)); 

    //set blocking 
    stream_set_blocking($fp,0); 

    //Check response 
    checkAppleErrorResponse($fp); 

    // Close the connection to the server 
    fclose($fp); 

    function checkAppleErrorResponse($fp) { 

     $apple_error_response = fread($fp, 6); //byte1=always 8, byte2=StatusCode, bytes3,4,5,6=identifier(rowID). Should return nothing if OK. 
     //NOTE: Make sure you set stream_set_blocking($fp, 0) or else fread will pause your script and wait forever when there is no response to be sent. 

     if ($apple_error_response) { 

      $error_response = unpack('Ccommand/Cstatus_code/Nidentifier', $apple_error_response); //unpack the error response (first byte 'command" should always be 8) 

      if ($error_response['status_code'] == '0') { 
       $error_response['status_code'] = '0-No errors encountered'; 

      } else if ($error_response['status_code'] == '1') { 
       $error_response['status_code'] = '1-Processing error'; 

      } else if ($error_response['status_code'] == '2') { 
       $error_response['status_code'] = '2-Missing device token'; 

      } else if ($error_response['status_code'] == '3') { 
       $error_response['status_code'] = '3-Missing topic'; 

      } else if ($error_response['status_code'] == '4') { 
       $error_response['status_code'] = '4-Missing payload'; 

      } else if ($error_response['status_code'] == '5') { 
       $error_response['status_code'] = '5-Invalid token size'; 

      } else if ($error_response['status_code'] == '6') { 
       $error_response['status_code'] = '6-Invalid topic size'; 

      } else if ($error_response['status_code'] == '7') { 
       $error_response['status_code'] = '7-Invalid payload size'; 

      } else if ($error_response['status_code'] == '8') { 
       $error_response['status_code'] = '8-Invalid token'; 

      } else if ($error_response['status_code'] == '255') { 
       $error_response['status_code'] = '255-None (unknown)'; 

      } else { 
       $error_response['status_code'] = $error_response['status_code'].'-Not listed'; 

      } 

      echo '<br><b>+ + + + + + ERROR</b> Response Command:<b>' . $error_response['command'] . '</b>&nbsp;&nbsp;&nbsp;Identifier:<b>' . $error_response['identifier'] . '</b>&nbsp;&nbsp;&nbsp;Status:<b>' . $error_response['status_code'] . '</b><br>'; 
      echo 'Identifier is the rowID (index) in the database that caused the problem, and Apple will disconnect you from server. To continue sending Push Notifications, just start at the next rowID after this Identifier.<br>'; 

      return true; 
     } 

     echo "\nPush respnse OK"; 
     return false; 
    } 
?> 

回答

1

,因为你使用的是不返回错误响应简单的二进制格式无法从苹果公司得到的错误响应:

$msg = chr(0) . pack('n', 32) . pack('H*', $token) . pack('n', strlen($payload)) . $payload; 

如果你想,可以返回一个错误响应的格式,您可以使用其中一种增强格式。

例如,以1开始的格式:

味精将与chr(1)开始,随后的4个字节的消息ID的,4个字节的期满时间和所述消息的其余部分将是相同什么你现在pack('n', 32) . pack('H*', $token) . pack('n', strlen($payload)) . $payload

有它应该是这样的:

$msg = chr(1) . pack("N", $msg_id) . pack("N", $expiry) . pack('n', 32) . pack('H*', $token) . pack('n', strlen($payload)) . $payload; 
+0

帮助我得到的错误,解决我的问题。谢谢。 –

+0

您可以详细介绍一下$ msg_id吗?它的意义是什么?它可以每次都是相同的数字,还是必须更改? – Ynhockey

+1

@Ynhockey关于$ msg_id的想法是,如果您使用$ msg_id == x发送推送通知,并且该通知被Apple拒绝(例如,由于设备令牌无效),您可以从Apple读取错误响应包含该ID x,它会让你知道哪些通知被拒绝(并且你必须重新发送在被拒绝的消息之后在同一连接上发送的所有通知,因为所有通知都被Apple忽略)。 – Eran