Техника 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);
И тогда вы просто проверяете токен устройства на отметку времени!
Только начал использовать эту библиотеку - отлично работает для меня!