PHP APNS Apple推送通知在每个请求中显示不同的响应代码

PHP APNS Apple推送通知在每个请求中显示不同的响应代码,php,push-notification,apns-php,Php,Push Notification,Apns Php,我有一个PHP脚本,可以向Apple APNS服务器发送推送通知。 它应该回显响应代码485,这表明消息已成功发送。但是,当我运行代码时,每次都会显示不同的数字代码,并且不会发送消息 代码如下: $payload = array( 'aps' => array( 'alert' => $message, 'T_ID' => $data["trip_id"], 'S' => $state, 'Api'

我有一个PHP脚本,可以向Apple APNS服务器发送推送通知。 它应该回显响应代码485,这表明消息已成功发送。但是,当我运行代码时,每次都会显示不同的数字代码,并且不会发送消息

代码如下:

$payload = array(
    'aps' => array(
        'alert' => $message,
        'T_ID' => $data["trip_id"],
        'S' => $state,
        'Api' => 2,
        'sound' => 'default'
));

$body = array();
$body['aps'] = array('alert' => "request trip");
$body['aps']['notifurl'] = $payload;
$body['aps']['badge'] = 2;
$payload = json_encode($body);
$ret = array(
    "error" => 0
);

$streamContext = stream_context_create();
stream_context_set_option($streamContext, 'ssl', 'local_cert', dirname(BASEPATH) . "/uploads/" . $this->_apnsCert);
stream_context_set_option($streamContext, 'ssl', 'passphrase', $this->_passphrase);
@$apns = stream_socket_client('tls://' . $this->_apnsHost . ':' . $this->_apnsPort, $error, $errorString, 200, STREAM_CLIENT_CONNECT, $streamContext);

if (!$apns) {
    //die('Error creating ssl socket ' . $error . ' ' . $errorString);
    $ret["error"] = 1;
    $ret["details"] = 'Error creating ssl socket ' . $error . ' ' . $errorString;
}

$apnsMessage = // Command "1"
    chr(1)
    // Identifier "88"
    . pack('N', 88)
    // Expiry "tomorrow"
    . pack('N', time() + 86400)
    // Token length
    . chr(0) . chr(32)
    // Device token
    . pack('H*', str_replace(' ', '', $deviceToken))
    // Payload length
    . chr(0) . chr(strlen($payload))
    // Actual payload
    . $payload . $payload;

echo fwrite($apns, $apnsMessage);
fclose($apns);

为什么这不能按预期工作?

我看到代码中至少有两个错误:

1当您使用json_encode$body编码消息正文时,$payload中的原始值被覆盖,尽管这可能不是最终的罪魁祸首

2您正在回显来自fwrite的结果,而您应该读取来自流的响应并回显该结果

请参见中的示例以了解如何处理返回值。以下代码由此派生:

// FUNCTION to check if there is an error response from Apple
// Returns TRUE if there was and FALSE if there was not
function checkAppleErrorResponse($fp) {
    //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. 

    $apple_error_response = fread($fp, 6);

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

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

    return false;
}

请注意,该示例建议您确保在读取流之前使用stream_set_blocking$fp,0将流设置为非阻塞模式,但这仅在您希望执行任何临时错误检查时才是必要的;您的代码示例没有做到这一点,因此对您来说可能不是问题。

我发现代码中至少有两个错误:

1当您使用json_encode$body编码消息正文时,$payload中的原始值被覆盖,尽管这可能不是最终的罪魁祸首

2您正在回显来自fwrite的结果,而您应该读取来自流的响应并回显该结果

请参见中的示例以了解如何处理返回值。以下代码由此派生:

// FUNCTION to check if there is an error response from Apple
// Returns TRUE if there was and FALSE if there was not
function checkAppleErrorResponse($fp) {
    //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. 

    $apple_error_response = fread($fp, 6);

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

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

    return false;
}

请注意,该示例建议您确保在读取流之前使用stream_set_blocking$fp,0将流设置为非阻塞模式,但这仅在您希望执行任何临时错误检查时才是必要的;您的代码示例没有做到这一点,因此对您来说可能不是问题。

当我使用fwrite回显响应时,我得到的响应代码为485!这意味着什么?返回写入流的字节数。这意味着$apnsMessage的长度是485字节,但与来自APNS服务器的响应无关。您需要使用fread来获得服务器响应,如上图所示。这是一个救生圈!我只想补充一点,最好是把sleep1;在函数之前,否则会出现一个空结果。。。如果你是批量发送推送,错误会显示为下一个错误。当我使用fwrite回显响应时,我得到的响应代码是485!这意味着什么?返回写入流的字节数。这意味着$apnsMessage的长度是485字节,但与来自APNS服务器的响应无关。您需要使用fread来获得服务器响应,如上图所示。这是一个救生圈!我只想补充一点,最好是把sleep1;在函数之前,否则会出现一个空结果。。。如果您正在批量发送推送,则错误可能会显示为下一个错误。