简体   繁体   English

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

[英]Push Notification (iOS) not recived/sent with PHP code

I'm trying to implement the APNS (Push notification). 我正在尝试实施APNS(推送通知)。 I've created the certificates, etc.. everything was created like iv'e done many many times. 我创建了证书,等等。一切都像创建了很多遍一样。 but i cant get an error from apple APNS server and it seems that everything is ok but i still not getting any push in the devices. 但是我无法从Apple APNS服务器得到错误,似乎一切正常,但是我仍然没有在设备中进行任何推送。 this is the PHP code I'm using to make the magic :) I ensure that the PORTS are open in the hosting. 这是我用来制作魔术的PHP代码:)我确保在主机中打开PORTS。

basically I'm getting the user token from the DB and sending the push text with default sound. 基本上,我是从数据库获取用户令牌,并使用默认声音发送推送文本。

can someone please look and tell me if you can see any problem in this code or let me know how can i get the real result of the process / response from APNS Server? 有人可以看一下并告诉我,如果您在此代码中看到任何问题,或者让我知道如何从APNS Server获得过程/响应的真实结果?

<?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;
    }
?>

You can't get error responses from Apple because you are using the simple binary format that doesn't return error responses : 您无法从Apple获得错误响应,因为您使用的是不返回错误响应的简单二进制格式:

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

If you want a format that can returns an error response, you can use one of the enhanced formats. 如果您想要一种可以返回错误响应的格式,则可以使用其中一种增强格式。

For example, the format that starts with 1 : 例如,以1开头的格式:

The msg would start with chr(1) , followed by 4 bytes of message ID, 4 bytes of expiration time and the rest of the message would be the same as what you have now pack('n', 32) . pack('H*', $token) . pack('n', strlen($payload)) . $payload 消息以chr(1)开头,后跟4个字节的消息ID,4个字节的到期时间,其余消息与您现在得到的pack('n', 32) . pack('H*', $token) . pack('n', strlen($payload)) . $payload pack('n', 32) . pack('H*', $token) . pack('n', strlen($payload)) . $payload

It should look like this : 它应该看起来像这样:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM