Способы угадать, подключен ли C2DM

Я пытаюсь сделать наилучшее предположение о том, могут ли быть получены сообщения C2DM.

Я создал приложение, которое использует передачу информации на телефон, когда он физически недоступен. Я понимаю, что C2DM не гарантирует доставку, но я хотел бы хотя бы знать, когда доставка сообщения вообще возможна; когда это не так, мы возвращаемся к нашей собственной службе push-уведомлений (и можем фактически сказать, когда мы подключены).

Я заметил, что C2DM на Android по-прежнему выдает токены аутентификации, даже если нет входа в учетную запись Google; сообщения по-прежнему кажутся доставленными в этом случае, хотя указано, что этого не должно быть. Если GTalk не подключен (брандмауэр или другие причины), при запросе токена аутентификации вообще не возвращается ответ. Токены аутентификации возвращаются в приложение, когда телефон находится в режиме полета. Это означает, что это не так просто, как проверить, доступен ли Интернет. Я не могу найти надежный способ проверить, зарегистрирован ли GTalk.

Опять же, мне не нужно гарантировать доставку сообщений, но я хотел бы хотя бы знать, возможна ли доставка. Есть у кого интересные решения?


person Ian Elliott    schedule 26.10.2011    source источник
comment
Просто нужно уточнение, вы хотите знать серверную часть, если вы можете связаться по телефону?   -  person Warpzit    schedule 26.10.2011
comment
Либо, либо было бы хорошо... Но главная цель состояла в том, чтобы иметь возможность сказать по телефону, подключен ли он, чтобы я мог открыть свое собственное TCP-соединение, если это необходимо.   -  person Ian Elliott    schedule 26.10.2011
comment
Afaik c2dm полагается на рынок, поэтому, если вы можете получить доступ к рынку и вы, конечно же, прошли проверку, вам должно быть ясно.   -  person Warpzit    schedule 26.10.2011
comment
Быть проверенным и иметь возможность активно получать сообщения — не одно и то же.   -  person Ian Elliott    schedule 26.10.2011


Ответы (8)


Посмотрите это видео, это доклад Google I/O о C2DM и о том, как его использовать. и как это работает. AFAIK, вы не можете знать, связано это или нет. Вероятно, большую часть времени они даже не знают (пока им не придется доставить сообщение и не потерпеть неудачу).

Однако настоятельно рекомендуется (в том числе и в видео) не отправлять важные данные через C2DM (поскольку сообщения могут потеряться). Услугу следует использовать только в качестве «сетевого ключа» (с минимально возможной площадью). Ваше приложение должно быть разбужено этим щелчком и должно начать извлекать необходимую информацию само.

Теперь, если вы реализуете это таким образом, должно быть легко реализовать механизм опроса. Поскольку вы уже отделили «щекотку» от фактического поиска информации, вы можете просто запускать поиск время от времени, если нет щекотки.

Что-то, что вы можете сделать, чтобы проверить, подключен ли C2DM, похоже на ping:

  1. Отправить сообщение на телефон через C2DM
  2. Приложение получает (или не получает) сообщение и отправляет «pong» обратно на ваш сервер.
  3. Сервер ждет «pong» в течение заданного времени (я бы сказал, 1-2 минуты), прежде чем пометить устройство как «не в сети».

Изменить: полагаться на GTalk невозможно. GTalk опирается на C2DM, как и ваше приложение, в нем нет ничего «лишнего». Кроме того, GTalk присутствует не на всех устройствах. Я не уверен, как приложение GTalk определяет, находится ли оно в автономном режиме или нет (к сожалению, оно не с открытым исходным кодом), но я предполагаю, что оно просто пытается пропинговать сервер и терпит неудачу.

person Felix    schedule 31.10.2011
comment
Я уже сделал именно то, что вы описываете, но я хотел бы сделать больше. Глядя на дампы logcat, GTalk знает точно, когда он подключен, и отправляет сообщения проверки активности каждые 300 секунд. У меня просто нет возможности подключиться к GTalk, чтобы спросить, подключен он или нет. GTalk не полагается на C2DM, он полагается на Jabber, а сообщения C2DM объединяются в спецификацию XMPP и доставляются через GTalk. Кроме того, если GTalk отсутствует, то C2DM не будет работать (это я действительно могу обнаружить и объяснить). - person Ian Elliott; 01.11.2011
comment
Откуда вы знаете, что C2DM не работает, если нет GTalk? Сталкивались ли вы с устройствами, в которых отсутствуют GTalk и C2DM? Я не уверен, что при отсутствии GTalk C2DM недоступен. Я не могу снова смотреть это выступление (это 1 час), но, насколько я помню, они сказали, что все их приложения (Gmail, GTalk и т. д.) используют одно и то же соединение C2DM для push-сообщений. То же соединение, которое в конечном итоге использует ваше приложение. GTalk может подключаться к Jabber при запуске приложения или при включенном экране, но это не относится к C2DM. - person Felix; 02.11.2011
comment
Кроме того, я не понимаю, что вы подразумеваете под сообщениями C2DM, включенными в спецификацию XMPP и доставляемыми через GTalk. Насколько я знаю (и я могу ошибаться), C2DM полностью отделен / отличается от XMPP или Jabber. А GTalk — это просто приложение. - person Felix; 02.11.2011
comment
Дальнейшая проверка показывает, что на самом деле он не зависит от GTalk, а скорее от GSF... но опять же, я не ищу гарантии доставки, просто некоторые эвристики, которые можно использовать, чтобы определить, возможна ли доставка. Я думаю, что причина, по которой Google не предлагает гарантированную доставку, заключается в дополнительных накладных расходах, необходимых для обеспечения ее получения телефоном. Бывший. Нет подключения к сети -› вероятность доставки 0%. Другие показатели могут улучшить мою догадку. - person Ian Elliott; 02.11.2011
comment
Это также зависит от того, где вам нужна эта информация. Если вам это нужно на стороне сервера, я думаю, что единственный способ узнать это — использовать метод ping, описанный в моем ответе. Если вам это нужно на устройстве, да, вы можете сделать некоторые другие вещи, такие как проверка сетевого подключения, а также попробовать простой запрос (например, HTTP-запрос к google.com или вашему собственному домену) и посмотреть, если вы получить что-нибудь. - person Felix; 02.11.2011
comment
Я хочу знать только по телефону. HTTP — достойное решение, но HTTP и C2DM используют разные порты, поэтому брандмауэры на самом деле не учитываются. - person Ian Elliott; 02.11.2011
comment
Вы можете настроить простой HTTP-сервер на порт 5228 (тот же порт, который использует C2DM) и попробовать отправить туда запрос. Хотя кажется, что это довольно большая головная боль. - person Felix; 03.11.2011
comment
Нужно использовать TCP-сервер, а не HTTP, чтобы быть более точным, поскольку некоторые брандмауэры фильтруют трафик по-разному, но да, это хороший момент. +1 за общий хороший совет. - person Ian Elliott; 04.11.2011
comment
Да, хороший момент. Однако, насколько я знаю (обратите внимание, что это совсем не моя территория, я могу ошибаться), C2DM выполняется через SSL. И когда вы делаете что-то через SSL, фактический протокол не фильтруется никакими брандмауэрами (потому что его нельзя прочитать). В этом случае вы можете просто настроить HTTPS-сервер на порт 5228, чтобы все упростить. - person Felix; 04.11.2011
comment
В телефонах Huawei не установлен GTalk и C2DM тоже не работает - person Mohsen Afshin; 29.06.2012

Нет, это невозможно. Поскольку ваше устройство аутентифицируется один раз, генерируете регистрационный идентификатор и отправляете его на сторонний сервер (как вы уже знаете). Теперь ваша работа заканчивается после регистрации устройства. Так что ждите сообщения, которое вы получили или нет (Нет гарантия доставки сообщения, так как C2DM использует протокол UDP).

Альтернативное решение

Хотя невозможно проверить со стороны Google напрямую, как я упоминал выше, но если вам срочно нужно проверить соединение с вашего телефона, вы можете использовать такой подход.

Шаг 1): Создайте один веб-сервис для проверки соединения

Шаг 2): вызовите эту веб-службу из приложения, которое отправит серверу команду отправить push-уведомление для проверки.

Шаг 3): теперь со стороны сервера сервер немедленно отправит push-уведомление для определенного устройства (от которого он получает команду)

Шаг 4): Теперь, если вы получили push-уведомление, это означает, что вы все еще подключены к C2DM.

это не займет много времени. Но следуйте ему только тогда, когда проверка соединения срочная и находится на пользователе.

person Tofeeq Ahmad    schedule 01.11.2011
comment
Я знаю, что невозможно проверить соединение, но можно увидеть вероятность соединения. В основном ищут любые данные, которые могут намекнуть на такое. - person Ian Elliott; 02.11.2011
comment
Я думаю, что нет, потому что в этом протоколе используется протокол, который не отвечает за гарантию доставки любого пакета и устанавливает соединение, когда ему нужно отправить сообщение. Поэтому я думаю, что невозможно проверить соединение, так как соединение отсутствует все время. - person Tofeeq Ahmad; 02.11.2011

Это может быть немного наивно, так как я не являюсь активным пользователем C2DM, но нельзя ли было прочитать

/proc/net/netstat

и посмотрите, есть ли активные TCP-соединения. Если их нет, то C2DM не может работать. Вы также можете сделать этот метод более универсальным, сформировав белый список C2DM, который вы ожидаете найти (или, может быть, его можно фильтровать на специальном порту C2DM?)

person Justin Breitfeller    schedule 03.11.2011
comment
Пока не могу попробовать, но скоро буду, звучит многообещающе! - person Ian Elliott; 04.11.2011

Если устройство недоступно, даже резервная система push-сообщений не будет работать. C2DM не гарантирует доставку вашего сообщения, но случай недоставки будет очень редким. Так было бы и в случае с любым другим сервисом. Лучший обходной путь, который вы могли бы найти, — это опросить ваш сервер, чтобы проверить, есть ли у вас какие-либо новые сообщения, которые еще не были доставлены. Я предполагаю, что ваше приложение таково, что очень важно не пропустить ни одного сообщения из 500 или, может быть, из 1000. В этом случае вы можете реализовать гибрид push и pull.

person Kumar Bibek    schedule 29.10.2011
comment
Чего-то я боялся, но это разрушает методологию толчка. Все еще надеюсь, что есть абстрактное решение, не связанное с опросом. - person Ian Elliott; 29.10.2011
comment
Ну, помните... Цель C2DM не в том, чтобы доставлять сообщения, когда нет доступного сетевого подключения. Цель C2DM состоит в том, чтобы позволить телефону свободно переходить в спящий режим, а не опрашивать сервер на предмет активности, будучи уверенным, что C2DM позволит серверу разбудить телефон и инициировать преднамеренную связь между телефоном и сервером, когда это произойдет. Образно говоря, C2DM — это дверной звонок (или сетевой эквивалент IRQ), а НЕ самостоятельный механизм доставки сообщений. Он пробуждает телефон и сообщает вашему приложению, что на сервере произошло что-то интересное. - person Bitbang3r; 06.11.2011

Я немного поработал с C2Dm, я создал свой сторонний пуш-сервер. Я реализовал небольшую логику, основанную на коде ответа C2DM http, чтобы узнать, было ли отправлено push-сообщение или нет. Вот часть кода, который я использовал:

int responseCode = conn.getResponseCode();

    if (responseCode == HttpServletResponse.SC_UNAUTHORIZED || responseCode == HttpServletResponse.SC_FORBIDDEN) {

        LOGGER.warn("Unauthorized - need token");

        return false;
    }

здесь я почти уверен, что push-сообщение было отправлено с серверов c2dm, потому что у меня есть идентификатор ответа:

if (responseParts[0].equals("id")) {
        LOGGER.info("Successfully sent data message to device: " + responseLine);

        return true;
    }

Я использовал другие методы, чтобы получить другие коды результатов от Google, если хотите, я могу опубликовать их. Надеюсь, я вам немного помог.

person moujib    schedule 31.10.2011
comment
Я также делаю то же самое на серверной части, но идентификатор из ответа только подтверждает, что сервер Google получил сообщение, а не то, получит ли его телефон. C2DM не предлагает никаких гарантий доставки. - person Ian Elliott; 01.11.2011

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

Помните, главное преимущество C2DM заключается в том, что он позволяет получать уведомления, когда телефон находится в спящем режиме и номинально отключен. Как только ваше приложение получит уведомление, мало что помешает вам разбудить телефон в этот момент, подключиться к сети и отправить подтверждение. Я не думаю, что вам даже нужно запрашивать разрешения «держать телефон в бодрствующем состоянии», потому что я считаю, что простого акта регистрации для уведомлений C2DM и их получения достаточно, чтобы разбудить телефон и позволить приложению продолжать работать в обычном режиме ( по крайней мере, достаточно долго, чтобы подключиться к сети и отправить подтверждение).

Пока вы это делаете, вы должны отслеживать подтверждения, которые происходят НАДОЛГО после того, как вы ожидали, что они будут безнадежными. Если вы видите больше, чем несколько, возможно, вам придется изменить стратегию повторной отправки.

Единственный реальный крайний случай, когда это может привести к сбою, — это если у вас есть пользователи, которые из кожи вон лезут, чтобы отключить передачу данных, оставив голосовую/SMS включенной (я почти уверен, что C2DM использует 4 байта ответной дейтаграммы, отправляемой, когда телефон опрашивает входящие). звонки и текстовые сообщения, которые изначально предназначались для RIM, а затем были перепрофилированы для Apple и Google).

person Bitbang3r    schedule 31.10.2011
comment
У меня тоже была такая идея, проблема в том, что этот метод информирует меня только о том, когда в последний раз было установлено соединение с сервером. Для меня это практически бесполезно, потому что невозможно определить, существует ли соединение, не отправив еще одно сообщение. - person Ian Elliott; 01.11.2011

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

person Buda Gavril    schedule 03.11.2011
comment
Идентификатор регистрации отправляется даже при отсутствии сетевого подключения... не совсем уверен, как он генерируется, и такое поведение кажется странным. Регистрация должна быть постоянной, и вы не должны регистрироваться повторно. - person Ian Elliott; 04.11.2011

Кое-что, связанное с длительным C2DM-соединением, которое используется для доставки триггеров:

  • В WLAN он отправляет пульс каждые 15 минут.
  • В мобильных сетях время ожидания составляет 28 минут.

28 минут могут быть слишком длинными, в зависимости от оборудования, используемого вашим оператором мобильной связи, повторителей 2G/3G в гаражах и т. д.

Вы можете получить много информации о соединении, открыв приложение Google Talk Service Monitor: http://www.honeytechblog.com/monitor-google-talk-service-android/

Наберите: ##8255##

Также есть кнопка, которая отправляет пульс прямо сейчас и сбрасывает тайм-аут.

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

person icyerasor    schedule 12.09.2012