Почему только некоторые устройства получают push-уведомления - PullRequest
4 голосов
/ 10 ноября 2010

Я настроил службу push-уведомлений для отправки уведомлений клиентам на основе RSS-канала.У меня есть служба, которая запускается каждую минуту, чтобы увидеть, было ли добавлено новое сообщение в канал.Если это так, служба отправит уведомление всем клиентам.Однако некоторые люди жалуются, говоря, что они не получают никаких push-уведомлений.Вот функция, которую я использую для отправки сообщений:

function _sendMessages($tokens, $message) {
        $payload['aps'] = array('alert' => $message, 'sound' => 'default');
        $payload = json_encode($payload);

        $context = stream_context_create();
        stream_context_set_option($context, 'ssl', 'local_cert', $this->certificate);
        stream_context_set_option($context, 'ssl', 'passphrase', '*********');

        $apns = stream_socket_client('ssl://' . $this->server . ':' . $this->port, $error, $errorString,60, STREAM_CLIENT_CONNECT, $context);

        foreach($tokens as $row) {
            $apnsMessage = chr(0) . chr(0) . chr(32) . pack('H*', str_replace(' ', '', $row->device_token)) . chr(0) . chr(strlen($payload)) . $payload;
            $fwrite = fwrite($apns, $apnsMessage);

            if (!$fwrite) echo 'push error';
            else echo 'push success';
        }

        fclose($apns);
    }

Я что-то не так делаю?Может ли PHP не справиться с выполнением этого цикла тысячи раз и потоковой передачей сообщений по соединению?

Ответы [ 3 ]

5 голосов
/ 27 января 2011

Кроме предложений, уже сделанных другими, вот контрольный список вещей, которые следует учитывать, когда толчки не работают.

  1. Если ваш общий push-пакет превышает 256 байтов, включая начальный заголовок, токен и полезную нагрузку JSON, APNS просто отбросит его. Если вы не используете «расширенное» обнаружение ошибок, вы никогда не узнаете, пока ваши пользователи не начнут жаловаться. Что вам нужно сделать, это проверить размер закодированного пакета, то есть размер фактических данных, которые вы перекачаете по проводам, и если он длиннее 256 байт, либо отклоните его, либо отрежьте часть текста сообщения и закодируйте это снова, пока это не будет <= 256 байтов длиной. </li>
  2. Если что-то не так с вашей полезной нагрузкой, включая длину, APNS отбросит ее, а APNS также прервет ваше соединение.
  3. Если у вас есть постоянное соединение, и оно простаивает около 20 минут или около того, APNS автоматически прервет соединение. Вы должны быть готовы к этому и восстановить соединение.
  4. Если срок действия вашего сертификата APNS истек или является неправильным, и вы продолжаете пытаться подключиться со слишком высокой скоростью, APNS будет заносить в черный список ваш IP-адрес в течение неизвестного периода времени, но это намного дольше, чем несколько минут, возможно, даже час или больше.
  5. Если у iPhone нет приема 3G, но есть WiFi, он попытается использовать его для push-уведомлений. Если вы находитесь в зоне брандмауэра, которая не разрешает исходящие подключения к сети Apple, ваш iPhone не сможет открыть сокет для APNS, и вы SOL.
  6. Я не уверен, что ваша БД SQL обновляется push-токенами каждый раз, когда клиент подключается к APNS. Наличие статической базы данных push-токенов - это проблема, потому что push-токены не остаются неизменными - об этом даже говорится в руководстве по программированию APNS. Предполагается, что iPhone будет получать push-токен при каждом запуске и передавать его на серверную часть (и я уверен, что вы можете оптимизировать это - iPhone может постоянно сохранять последний токен и отправлять его, только если он изменился). Но некоторые вещи могут вызвать изменение push-токена, например, перерегистрация iPhone для push, и я не уверен, что еще. Все, что я знаю, это то, что использование push-токена, похожего на GUID, вызывает проблемы. В следующий раз, когда токен изменится, если ваша БД не будет обновлена, до свидания отправьте этому клиенту.

Надеюсь, это поможет.

1 голос
/ 12 ноября 2010

Я думаю, что здесь есть 3 потенциальных проблемы:

1) Вы подключаетесь слишком часто (возможно, чаще, чем вы думаете), и Apple отказывается / разрывает соединение, потому что считает вас слишком спамом. Это было бы довольно очевидно, если честно - ваш fwrite потерпит неудачу, потому что поток пропал бы.

В идеале APNS - это соединение, которое удерживается открытым как можно дольше (10 минут - это время бездействия, которое мы используем), а не восстанавливать его каждую минуту. SSL-согласование стоит ЦП, но соединение остается открытым относительно дешево. Поэтому я буду держать это соединение открытым между запусками, если вы можете, и автоматически восстанавливать его, если оно было разорвано по любой причине.

2) Вы не проверяете ошибки. См. Руководство APNS, но оно может отвечать по тому же соединению сообщениями об ошибках, и вы просто игнорируете это. Я думаю, что каждый раз в цикле вы должны проверять, есть ли какие-либо данные для чтения, читать их и интерпретировать как пакет с ошибкой. По крайней мере, вы должны записывать ответы об ошибках.

3) Это длинный выстрел. Возможно ли, что вы на самом деле удалили этих пользователей, возможно, из-за того, что служба обратной связи сказала вам об этом? Если пользователь был отключен в течение длительного времени, служба не сможет доставлять уведомления, и он может сказать вам, чтобы удалить эти устройства из вашего списка. Если вы не переподписываете этих пользователей (или хотя бы подтверждаете, что они все еще подписаны) при запуске приложения, тогда они будут думать, что они подписаны на уведомления, хотя на самом деле вы уже решили забыть о них.

0 голосов
/ 10 ноября 2010

Хм ... Я не вижу в этом ничего плохого. Действительно ли клиенты включили push-уведомления для вашего приложения?

...