【问题标题】:PHP APNS Apple Push Notifications shows different response code every requestPHP APNS Apple Push Notifications 显示每个请求的不同响应代码
【发布时间】:2016-10-20 05:44:50
【问题描述】:

我有一个向 Apple APNS 服务器发送推送通知的 PHP 脚本。 它应该回显响应代码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);

为什么这没有按预期工作?

【问题讨论】:

    标签: php push-notification apns-php


    【解决方案1】:

    我在代码中看到至少 2 个错误:

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

    2) 当您应该从流中读取响应并且 echoing 时,您正在 echoing 来自 fwrite 的结果。

    查看Working with Apple Push Notification 的示例以了解如何处理返回值。以下代码源自那里:

    // 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!这是什么意思?
    • fwrite() function 返回写入流的字节数。这意味着$apnsMessage的长度为485字节,但与APNS服务器的响应无关。需要使用fread()来获取服务器响应,如上图。
    • 这是一个救生员!我只想补充一点,最好把 sleep(1);在函数之前,否则它会产生一个空结果......如果您批量发送 PUSH,则错误可能会显示为下一个错误。
    猜你喜欢
    • 1970-01-01
    • 2017-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-08
    • 1970-01-01
    相关资源
    最近更新 更多