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

Может кто-то уточнить, что APNs (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() это неправильный способ сделать это.

Спасибо

5 ответов

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

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

Вот полная функция для извлечения токенов устройств с серверов обратной связи 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
    ),
)

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

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

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

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

"Ну, как бы глупо это ни звучало, я нашел решение:

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

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

$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);

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

Только начал использовать эту библиотеку - отлично работает для меня!

https://github.com/mac-cain13/notificato

Другие вопросы по тегам