klink0v (klink0v) wrote,
klink0v
klink0v

Летит Push-а, нельзя скушать, часть 2

Продолжение предыдущего поста.

Чего же придумали эти хитропопые инженеры в попытке нейтрализовать негативные эффекты, возникающие вследствие взаимодействия мобильных приложений с внешним миром? А давайте, говорят, введём в цепь обмена данными между клиентом и сервером двух посредников: специальную системную службу на телефоне и специальный "центральный" сервер, с которым будет соединяться та самая специальная системная служба. Так появился Push.

Другими словами, пока приложение работает в foreground-е (то бишь активно), оно может без ограничений общаться с кем хочет, когда хочет и в любых количествах. Но как только оно уходит в background (в "фон") неважно по какой причине, "засыпает". А заснув, лишается возможности что-либо отправлять или принимать. Но при этом может попросить системную службу "разбудить" себя либо по таймеру (например, через N секунд), либо по событию (что-то пришло снаружи).

Но как оно получит что-то снаружи, ежели само спит? А очень просто. Отправитель сообщения сперва передаст его на сервер Google / Apple / Microsoft в зависимости от марки устройства. Тот, в свою очередь, найдёт заранее установленную TCP-сессию до push-службы телефона и передаст сообщение ей. А уже push-служба, в свою очередь, разбудит приложение, передаст ему управление и скажет что надо делать.

Вроде бы как всем хорошо. Покуда экран аппарата выключен, все спят. Только шофёр push-агент не спит. Он героически "держит" одну-единственную TCP-сессию с одним-единственным сервером, причём без большой и малой нужды никакие данные через неё не гоняет. Таким образом, и радиомодули тоже спят. А push-сервер тоже, сцуко, хитрый. Если на него придёт ряд однотипных сообщений, то он сначала выжидает минуту-другую, дабы поднакопить их. А потом "выстреливает" всё это на клиентское устройство одной большой пачкой, чтобы избежать серии последовательных включений-выключений радиопередатчика. Это называется "throttling" (не путать с троллингом). Казалось бы, идиллия и рай на Земле.

Но нет. Как всегда, здесь появляется куча разных побочных эффектов.


  1. Некоторые производители в дополнение к "стандартным" технологиям энергосбережения добавляют свои собственные. Особенно этим любят баловаться Sony и Samsung. Что именно они "доделывают", доподлинно неизвестно. То ли отправляют в глубокий сон самого push-агента, то ли принудительно отключают всю связь. Но факт остаётся фактом. Меньше всего проблем с Push-ем наблюдается на "родных" Nexus-ах, больше всего — на изделиях вышеупомянутых брендов.

  2. На устройстве либо где-нибудь "по дороге" могут присутствовать антивирусы / файрволлы, которые вмешиваются в работу push-механизма и частенько ломают его.

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

  4. Если у аппарата присутствуют и Wi-Fi, и GPRS модули, то push будет всегда предпочитать GPRS ввиду его бо́льшей энергоэффективности для обмена небольшим количеством данных. Часто даже случается, что телефон ингорирует настройку "передача данных через сотовые сети" и всё равно начинает использовать GPRS, даже если пользователь его отключил. Иногда это становится источником заметных непредвиденных финансовых расходов в роуминге. А бывает и наоборот. Допустим, имеется стабильный приём сигнала по Wi-Fi и очень неустойчивый через GPRS. Пользователь наивно полагает, что всё хорошо и он на связи, только вот push-и скорее всего не дойдут. А вместе с ними "потеряется" и уведомление о каком-нибудь важном входящем сообщении.

  5. Push-агент и push-сервер периодически пингуют друг друга с некоторым интервалом дабы убедиться, что TCP-сессия ещё жива-здорова. Это называется "heartbeat". В андроиде пресловутый интервал равен 15-ти минутам для Wi-Fi и 28 минутам для GPRS. И вот тут начинаются всякие интересности. Если, например, домашний маршрутизатор, либо NAT интернет-провайдера оборвёт неактивную TCP-сессию раньше, чем пройдёт 15 минут, то с момента разрыва до окончания этого интервала push гарантированно перестанет работать. То же самое произойдёт, и в том случае, если после "пробуждения" беспроводного интерфейса DHCP-сервер выдаст телефону другой IP-адрес.

  6. А ведь операторы сотовой связи (ОПСОСы) в России тоже выдают исключительно "серые" адреса, трафик с которых потом и фильтруют, и маскарадят (NATят). Каким образом они это делают, какие ограничения по количеству одновременно открытых TCP-сессий и какие тайм-ауты неактивности выставляют на своём оборудовании — никто кроме них самих не знает. То есть, вполне может произойти, что при перемещении из одной соты в другую либо через 5...10 минут все установленные с вашего устройства сессии принудительно оборвут на стороне оператора. Что при этом случится с push-ем, наверное, сами догадаетесь.

Таким образом выясняется, что механизм push — крайне ненадёжный и ломается от малейшего дуновения. И одно дело, когда таким образом тебе сообщают о погоде на завтра или выходе нового ролика на Youtube. И другое дело, когда ты ждёшь важное сообщение в электропочту или мессенджер. Естественно, программистов такой расклад совершенно не устраивает, и они начинают лепить и вставлять костыли различной степени корявости, так или иначе приводящие к увеличению расхода трафика и ускорению разряда батареи. Что они могут предпринять.


  • Принудительно запретить телефону гасить радиомодули и выгружать приложение. Тут понятно, это совсем жесть.

  • Не надеясь на push, установить и поддерживать отдельное постоянное TCP-соединение со своим собственным сервером.

  • Как разновидность предыдущего варианта, периодически (например, раз в минуту) "будить" собственное приложение по системному таймеру, пинговать свой сервер для проверки наличия отклика и актуальности TCP-сессии, после чего "засыпать" обратно. То есть best practise violation в чистом виде.

  • Собирать статистику по задержкам поступления push-сообщений. Если они находятся в разумных пределах, то продолжать использовать push. Если нет — применить какой-то из вышеописанных способов.

Эти костыли такие костыли. Но конкретно меня больше всего огорчает даже не это. Допустим, есть некая SIP-трынделка. Если нужный нам SIP-регистратор не поддерживает TCP, то это вообще клиника. Регистрация сто пудово отвалится очень быстро. Либо придётся постоянно держать включёнными радиомодули. Но предположим, что всё не так плохо.

В таком случае в целях экономии батарейки было бы очень круто постоянно "спать", а информацию о входящем вызове получать через push. Та же самая Bria, кстати, умеет так делать. Но после осознания механизмов, лежащих в основе push-а стало понятно, что это ни разу не надёжный метод. Пропущенные звонки практически гарантированы. Остаётся только всегда поддерживать собственную TCP-сессию, периодически "подновляя" её. Другими словами, запущенный на смартфоне VoIP-клиент — это всегда "до свиданья" аккумулятору, как ни крути.

И теперь мне стало понятно, почему иногда сообщения в WhatsApp приходят с большой задержкой, иногда до получаса. Но программисты в этом не виноваты. Против нас выступает само мироздание. А также ОПСОСы.

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

При написании этого псто использовались следующие статьи: раз, два, три, четыре, пять.

Tags: android, ОПСОСы, сети, ссылки, технологии
Subscribe
  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

  • 19 comments