PHP APNS Apple Push Notifications показывает разный код ответа на каждый запрос

У меня есть сценарий PHP, который отправляет push-уведомления на сервер 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);

Почему это не работает должным образом?


person Wael Salah    schedule 18.06.2016    source источник


Ответы (1)


Я вижу как минимум 2 ошибки в коде:

1) исходное значение в $payload перезаписывается, когда вы кодируете тело сообщения с помощью json_encode($body), хотя это, вероятно, не окончательный виновник

2) вы echo просматриваете результат fwrite, тогда как вы должны читать ответ из потока и echo обрабатывать его.

См. Пример на странице Работа с Apple Push-уведомление, чтобы понять, как обрабатывать возвращаемые значения. Следующий код получен оттуда:

// 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) перед чтением из него, но это необходимо только в том случае, если вы хотите выполнить какую-либо промежуточную проверку ошибок; в вашем примере кода этого не происходит, поэтому для вас это может не быть проблемой.

person Michael Gaskill    schedule 18.06.2016
comment
Когда я повторяю ответ с помощью fwrite, я получаю код ответа 485! что это значит? - person Wael Salah; 19.06.2016
comment
Функция fwrite () возвращает количество байтов, записанных в поток. Это означает, что длина $apnsMessage составляет 485 байтов, но не имеет ничего общего с ответом сервера APNS. Вам нужно использовать fread(), чтобы получить ответ сервера, как показано выше. - person Michael Gaskill; 19.06.2016
comment
Это спасатель! Я просто хочу добавить, что лучше всего усыпить (1); перед функцией, иначе будет пустой результат ... и если вы отправляете PUSH в пакете, ошибка может отображаться, как если бы она была для следующего. - person Виктор Иванов; 27.09.2016