Как стать автором
Обновить

Комментарии 16

Какое-то время сам рассматривал работу с push, но, из-за недостатка времени, пока отложил. И искал я реализации без использования fcm.
Все упоминания и реализации push непременно связаны с fcm. Да, это, конечно, удобно, что не нужно заморачиваться с сервером и разницей реализации в разных браузера, но этот вариант не особо подходит для целей, когда одним из требований является работа только с локальными ресурсами (например, когда web недоступен).
Плюс, хотелось бы понимать что происходит «под капотом» библиотек, которым безоговорочно доверяют.

К сожалению, без FCM это будет сделать довольно тяжело и не будет нативной поддержки Chrome/Android (они жестко завязаны на FCM), да и сама технология подразумевает использование 3rd-party серверов.
Про то, что происходит "под капотом" у Firebase SDK на клиентской стороне (в браузере) я тоже планирую написать.
Отображение же уведомлений что в бразуерах, что на Android можно делать независимо от собственно пуш-системы. Как там у iOS с этим дела обстоят, сходу не могу сказать. Но для этого нужно будет поднимать собственную инфраструктуру, хотя те же OpenPush или AutoPush (существует аж в трех вариантах) могут с этим помочь

Когда только начинал разбирать с этими уведомлениями, был неприятно удивлён, что нет API для них. Хотя, казалось бы, всё стандартизовано. Возможно, всё упирается в требование сервера, но можно было бы создать «общие» сервера (для fcm же есть) и при отправке запроса указывать адрес, например. Как появится время, буду заново разбирать. Может в каком-то моменте есть продвижения.
Если нужны только web пуши, то там всё довольно несложно, гуглосервисы, вроде fcm, для этого не нужны. Само api стандартизировано и одинаково для любых браузеров (некоторые фичи, вроде кнопок, поддерживаются только хромом).
Я реализовывал серверную часть на php с помощью вот этого компонента minishlink/web-push. Задача клиентской части в этом случае запросить разрешение на подписку и выслать на сервер три параметра endpoint, publicKey и authToken, это данные одного конкретного получателя.
Сервис воркер остается примерно таким же, как у автора.
Спасибо, гляну, как появится время.
Простите за банальный вопрос, но почему не вебсокеты или sse?

Эти технологии решают несколько иные задачи. Если вебсокеты/sse нужны для обновления состояния приложения в реальном времени, то пуши — скорее для оповещения пользователя. Да, можно получать события по sse или вебсокету и показывать уведомления, однако с этим есть несколько проблем:


  • Нужно строить свою инфраструктуру почти что с нуля, это довольно дорого и долго
  • Пуш-уведомления приходят через одно единственное соединение на весь браузер или мобильное устроиство. Если в браузере никто не мешает перенести подключение в сервис-воркер, то в мобильных устроиствах это, во-первых, не всегда возможно (насколько я знаю, в iOS очень жесткие требования по фоновой работе), во-вторых, ускоряет разряд батареи

Спасибо за ответ, всё по делу. по сути оповещения пользователя ту же задачу решают — обновление данных приложения. Отложенные или рилтайм — это уже вопрос реализации протокола и инфраструктуры. Я подобную систему делал на го, не могу сказать что это было мега дорого и проблематично, но конечно от задачи зависит. По поводу хттп соединений — современные фронтенд приложения их много открывают и ни разу на них не экономят. Мне трудно оценить стоимость хттп коннекта в единицах времени работы аккумуляторной батареи, но по опыту разработки мобильного натив софта не заметил влияния. Если покажете бенчмарки, буду признателен.

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

Судя по тому, что я читал, там действительно за общение с сервером отвечает отдельный процесс, который при получении данных отправляет нужному приложению Intent. Про использование полуоткрытых соединений ни разу не слышал, да и это вроде как ошибочная ситуация. Точнее сказать сложно, так как сам в этом не разбирался. Если разберусь, постараюсь об этом написать.

Можете показать формат отправляемого уведомления, где разница между notification и data?

Вариант с notification:


Скрытый текст
{
 "to" : "<token>",
 "notification" : {
     "body" : "Body of Your Notification",
     "title": "Title of Your Notification"
 }
}

Приходит вот так:


Скрытый текст
{"from":"514044135031","priority":"normal","notification":{"title":"Title of Your Notification","body":"Body of Your Notification"},"collapse_key":"do_not_collapse"}

Вариант с data:


Скрытый текст
{
 "to" : "<token>",
 "data": {
    "key1": "value1",
    "key2": "value2"
 }
}

Приходит вот так:


Скрытый текст
{"data":{"key1":"value1","key2":"value2"},"from":"514044135031","priority":"normal","collapse_key":"do_not_collapse"}
Посмотрел на OpenPush, но не нашёл ответа на главный (для меня) вопрос. В Android, начиная с версии 6.0, есть так называемый режим Doze. Суть его вкратце в том, что чем дольше приложение висит в background-е без взаимодействия с пользователем, тем реже и меньше квантов времени ему выделяется системным планировщиком. Т.е. даже если ты держишь собственное соединение с сервером и периодически шлёшь keep-alive пакеты, это никак не спасает – через некоторое время, проведённое в фоне, приложение будет фактически поставлено на паузу с очень редкими, короткими и нерегулярными пробуждениями. Единственный, кто может в этом случае разбудить приложение – системный сервис Google, который держит постоянное соединение с серверами Google, и на который не распространяются ограничения режима Doze (потому что это специализированный системный сервис, подписанный ключом Google, о котором знает производитель устройства, и потому даёт ему повышенные права). Вот этот-то сервис и может получить push (очевидно, что в данном случае это только Firebase Cloud Message) и разбудить заснувшее приложение, послав ему Intent, даже если оно сейчас doze-ировано. Чтобы такими же правами обладал сторонний сервис, надо просить каждого пользователя вручную выключать «Battery optimization» для вашего приложения (нет, автоматически это сделать нельзя). Но это дело гиблое, как правило. Многие проигнорируют, многие сначала сделают так, а потом, под влиянием ли момента, забыв ли, или ещё по какой-то причине, опять включат «Battery optimization». И все. Все ваши пуши будут доставляться с задержкой в несколько часов или же и вовсе будут теряться.

Т.е. дело-то не в технологии как таковой. Альтернативы гугловскому firebase нет не потому, что там какая-то секретная волшебная технология, а потому, что тупо у сервиса права есть, которых нет у вашего приложения. И этот вопрос никак не проясняется на сайте OpenPush. Или я плохо искал?

Openpush лично не испытывал (включил в статью, чтобы было понимание о наличии альтернативных решений), но, скорее всего, вы правы и "оптимизацию батареи" для него придется отключать вручную для стабильной работы. И, кстати, "невидимые" для пользователя data-пуши используют иногда в том числе и для того, чтобы "разбудить" приложение (мы сейчас исследуем эту возможность)

«Разбудить» приложение — это хороший рабочий вариант. Размер пуша ограничен и много данных в нём не передашь. Хоть время работы приложения после получения пуша ограничено, но для пары тройки запросов и обновления данных в фоне хватает с головой (показать пуш, обновить ленту новостей и тп).
Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.