Подтвердить что ты не робот

Технология PHP для запроса сервера обратной связи APNs

Может кто-нибудь уточнить, что APN (Apple Push Notification) хочет, насколько вы его запросите?

Документы говорят, что он начинает отправлять, как только будет установлено соединение. Означает ли это, что я не делаю fread() на нем?

Вот мой текущий код, чтобы попробовать его прочитать. Я не помещал fread() в цикле, так как не знаю, какой ответ указывает "больше нет записей для чтения", и я не хотел бесконечного цикла на моем сервере.

<?php
$apnsCert = 'HOHRO-prod.pem';

$streamContext = stream_context_create();
stream_context_set_option($streamContext, 'ssl', 'local_cert', $apnsCert);
stream_context_set_option($streamContext, 'ssl', 'verify_peer', false);

$apns = stream_socket_client('ssl://feedback.push.apple.com:2196', $error, $errorString, 60, STREAM_CLIENT_CONNECT, $streamContext);

echo 'error=' . $error;
echo 'errorString=' . $errorString;


$result = fread($apns, 38);
echo 'result=' . $result;


fclose($apns);
?>

Пока все, что я получаю, это пустой ответ. Ошибок нет, поэтому он подключается.

Я не знаю, означает ли нулевой ответ отсутствие данных, или мой fread() - неправильный способ сделать это.

Спасибо

4b9b3361

Ответ 1

Вот большой gotcha, который смутил меня, когда я впервые попытался подключиться: серверы обратной связи APNS только возвращают токены устройства, которые "истекли" с момента последнего запроса обратной связи. Это означает, что большую часть времени вы получите ответ NULL, если вы уже имеете дело с большим количеством пользователей вашего приложения.

Поэтому убедитесь, что вы сохранили токены истекшего устройства на диске или db, потому что после вашего запроса обратной связи они ушли навсегда. Это заставляет испытывать боль, если не сказать больше!

Здесь представлена ​​полная функция для извлечения токенов устройства с серверов обратной связи APNS (многие благодаря ответам выше, чтобы помочь мне собрать все вместе):

function send_feedback_request() {
    //connect to the APNS feedback servers
    //make sure you're using the right dev/production server & cert combo!
    $stream_context = stream_context_create();
    stream_context_set_option($stream_context, 'ssl', 'local_cert', '/path/to/my/cert.pem');
    $apns = stream_socket_client('ssl://feedback.push.apple.com:2196', $errcode, $errstr, 60, STREAM_CLIENT_CONNECT, $stream_context);
    if(!$apns) {
        echo "ERROR $errcode: $errstr\n";
        return;
    }


    $feedback_tokens = array();
    //and read the data on the connection:
    while(!feof($apns)) {
        $data = fread($apns, 38);
        if(strlen($data)) {
            $feedback_tokens[] = unpack("N1timestamp/n1length/H*devtoken", $data);
        }
    }
    fclose($apns);
    return $feedback_tokens;
}

Если все хорошо, возвращаемые значения из этой функции будут выглядеть примерно так (через print_r()):

Array
(
    Array
    (
        [timestamp] => 1266604759
        [length] => 32
        [devtoken] => abc1234..............etcetc
    ),
    Array
    (
        [timestamp] => 1266604922
        [length] => 32
        [devtoken] => def56789..............etcetc
    ),
)

Ответ 2

Этот код выглядит правильно, однако вам нужно выполнить цикл и проверить конец потока, чтобы прочитать все коды устройств.

 while (!feof($apns)) {
        $devcon = fread($apns, 38);
 }

Однако моя проблема заключается в фактической распаковке данных. Кто-нибудь знает, как распаковать двоичные данные, которые вы только что прочитали, чтобы получить фактический идентификатор устройства (как строку) вместе с меткой времени и т.д.

Ответ 3

Я получил решение от яблочного форума, и он предназначен для разработки. Попробуйте это также для производства.

"Ну, как ни странно, я нашел решение:

Создайте фиктивный идентификатор приложения на портале программы, включите оповещения о развертывании на нем Создайте и загрузите связанный профиль обеспечения Создайте новый проект xcode и вызовите метод registerForRemoteNotificationTypes при запуске. Установите фиктивное приложение на свое устройство. На этом этапе на вашем устройстве должно быть два приложения РАЗРАБОТКИ: оригинальное приложение и фиктивное приложение. Оба должны быть зарегистрированы для получения push-уведомлений. Удалите исходное приложение и попробуйте отправить push-уведомление этому приложению. Вызовите службу обратной связи, и вы должны получить данные назад. "

Ответ 4

Это, наконец, сработало для меня.

$arr = unpack("H*", $devconts); 
$rawhex = trim(implode("", $arr));

$feedbackTime = hexdec(substr($rawhex, 0, 8)); 
$feedbackDate = date('Y-m-d H:i', $feedbackTime); 
$feedbackLen = hexdec(substr($rawhex, 8, 4)); 
$feedbackDeviceToken = substr($rawhex, 12, 64);

И тогда вы просто проверяете токен устройства на отметку времени!