PHP: отправка Push-уведомлений в ios
я отправляю push-уведомления с php на ios. Он работает нормально, и вот мой код:
$passphrase = '';
$badge = 1;
$path = base_path('path/to/certificate.pem');
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', $path);
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);
$fp = stream_socket_client(
'ssl://gateway.sandbox.push.apple.com:2195', $err,
$errstr, 60, STREAM_CLIENT_CONNECT | STREAM_CLIENT_PERSISTENT, $ctx
);
if (!$fp) {
self::SavePush($device_token, $message, $device_id, $device_type, $user_id, "pending", "normal", null);
}
//echo 'Connected to APNS' . PHP_EOL;
$body['aps'] = array(
'alert' => $message,
'badge' => $badge,
'sound' => 'default'
);
$payload = json_encode($body);
$msg = chr(0) . pack('n', 32) . pack('H*', $device_token) . pack('n', strlen($payload)) . $payload;
$result = fwrite($fp, $msg, strlen($msg));
//print_r($result);exit;
if (!$result) {
self::SavePush($device_token, $message, $device_id, $device_type, $user_id, "pending", "normal", null, $result);
} else {
self::SavePush($device_token, $message, $device_id, $device_type, $user_id, "sent", "normal", null, $result);
}
fclose($fp);
Теперь проблема, с которой я сталкиваюсь, я не могу определить, если уведомление не удается как $result
содержится целое число в каждом случае, успех или неудача. Я передал случайную цифру как токен, и она возвращает целое число, такое как 115 или 65, и она меняется каждый раз. Так что !$result
не будет работать. Как узнать, если уведомление не удается?
3 ответов
вызов fwrite() вернет количество успешно отправленных байтов или вернет FALSE, если произошла ошибка отправки. Ваш результат $изменяется, потому что он изменяется с размером отправляемого сообщения. Зная это, вы можете предположить, что если $result===FALSE, то произошла ошибка и уведомление не удалось. Если $ результат!= = FALSE, затем уведомление было успешно отправлено. Это только подтверждает, что сообщение было отправлено по сети. Он не проверяет, что структура сообщения или действительность токенов или что-то в этом роде.
теперь, если вы пытаетесь выяснить, действительно ли само сообщение push-уведомления и что apple приняла и обрабатывает его, то вы, вероятно, хотите свернуться и HTTP/2 для этого. Делать быстрый поиск Google, я наткнулся на этот сайт, который показывает демо, как это сделать. Я не тестировал этот сайт http://coding.tabasoft.it/ios/sending-push-notification-with-http2-and-php/ так не могу сказать вы, если демо правильно или нет. Это был просто быстрый поиск, но, возможно, вы на правильном пути.
после того, как вы отправите что-то в APNS с fwrite
вам понадобится fread
(или stream_get_contents
;)) ответ. Лучший способ-использовать неблокирующее соединение (stream_set_blocking($fp, 0);
) и ждать ответа в простом ограниченном по времени цикле:
$read = '';
$to = time() + 2; // max 2 seconds wait...
while (!feof($fp)) // ...or end of connection
{
$r = stream_get_contents($fp);
if (strlen($r) > 0)
$read .= $r;
if (time() >= $to)
break;
usleep(100000);
}
после этого, в $read
у вас будет либо что-то, либо ничего. Что-то (ровно с 6 байтами) означает ошибку ($error = unpack('Ccommand/Cstatus/Nident', $read);
). Ничто (или содержимое короче/длиннее 6 байт) не означает успешно отправленное сообщение.
мои два цента, чтобы прояснить важный момент: как заявляет Apple, "нет гарантии доставки", поскольку push работает таким образом.
таким образом, вы можете, конечно, проверить на сетевые ошибки, как предложили другие ребята, но у вас нет гарантии, что уведомление не было получено. Чтобы получить так, единственное (long..) способ-вызвать запрос URL в устройстве iOS, когда он получает толчок. Этот запрос URL обновит вашу БД.