【问题标题】:Push Notification (iOS) not recived/sent with PHP code未使用 PHP 代码接收/发送推送通知 (iOS)
【发布时间】:2014-06-22 13:39:17
【问题描述】:

我正在尝试实现 APNS(推送通知)。 我已经创建了证书,等等。一切都是像我已经完成了很多次一样创建的。 但我无法从苹果 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;
    }
?>

【问题讨论】:

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


    【解决方案1】:

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

    $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; 
    

    【讨论】:

    • 帮助我解决了错误并解决了我的问题。谢谢。
    • 你能详细说明一下$msg_id吗?它的意义是什么?每次都可以是相同的数字,还是必须改变?
    • @Ynhockey 关于 $msg_id 的想法是,如果您发送带有 $msg_id == x 的推送通知并且该通知被 Apple 拒绝(例如,由于无效的设备令牌),您可以阅读来自 Apple 的包含该 ID x 的错误响应,它将让您知道哪个通知被拒绝(并且您必须在被拒绝的消息之后重新发送您在同一连接上发送的所有通知,因为所有通知都被忽略了苹果)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-05
    • 1970-01-01
    • 1970-01-01
    • 2017-10-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多