使用PHP代码未接收/发送推送通知(iOS)

时间:2014-06-22 13:39:17

标签: php ios push-notification apple-push-notifications apns-php

我正在尝试实施APNS(推送通知)。 我已经创建了证书等等。一切都是像iv'e做了很多次。 但我不能从苹果APNS服务器得到一个错误,似乎一切都好,但我仍然没有得到任何推动设备。 这是我用来制作魔法的PHP代码:) 我确保PORTS在托管中开放。

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

有人可以看看并告诉我你是否可以在这段代码中看到任何问题,或者让我知道如何从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 个答案:

答案 0 :(得分:1)

您无法从Apple获得错误响应,因为您使用的是不会返回错误响应的简单二进制格式:

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

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

例如,以1:

开头的格式

msg将以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;