Это пост №9 из серии, посвященной изучению JavaScript и его компонентов. В процессе идентификации и описания основных элементов мы также делимся некоторыми практическими правилами, которые мы используем при создании SessionStack, легкого приложения JavaScript, которое должно быть надежным и высокопроизводительным, чтобы помочь пользователям увидеть и воспроизвести дефекты веб-приложений в реальных условиях. -время.
Если вы пропустили предыдущие главы, вы можете найти их здесь:
- Обзор движка, среды выполнения и стека вызовов
- Внутри движка Google V8 + 5 советов по написанию оптимизированного кода
- Управление памятью + как справиться с 4 распространенными утечками памяти
- Цикл событий и рост асинхронного программирования + 5 способов улучшить кодирование с помощью async / await
- Глубокое погружение в WebSockets и HTTP / 2 с SSE + как выбрать правильный путь
- Сравнение с WebAssembly +, почему в некоторых случаях лучше использовать его поверх JavaScript
- Строительные блоки Web Workers + 5 случаев, когда вы должны их использовать
- Сервис-воркеры, их жизненный цикл и сценарии использования
Сегодня мы обращаем внимание на веб-push-уведомления: мы рассмотрим их составляющие, исследуем процессы, лежащие в основе отправки / получения уведомлений, и в конце расскажем, как мы в SessionStack планируем использовать их для создания новых функций продукта.
Push-уведомления очень распространены в мобильном мире. По той или иной причине они вошли в Интернет довольно поздно, хотя разработчики очень востребовали эту функцию.
Обзор
Веб-push-уведомления позволяют пользователям подписаться на получение своевременных обновлений из веб-приложений, которые направлены на повторное привлечение их пользовательской базы контентом, который может быть интересным, важным и своевременным для пользователей.
Push основан на Service Workers, о которых мы подробно говорили в предыдущем посте.
Причина использования Service Workers в этом случае заключается в том, что они работают в фоновом режиме. Это отлично подходит для push-уведомлений, потому что это означает, что их код выполняется только тогда, когда пользователь взаимодействует с самим уведомлением.
Отправить уведомление
Push и уведомление - это два разных API.
- Push - вызывается, когда сервер предоставляет информацию Service Worker.
- Уведомление - это действие Service Worker или скрипта в веб-приложении, которое показывает информацию пользователю.
Толкать
Есть три основных шага для реализации push:
- Пользовательский интерфейс - добавление необходимой клиентской логики для подписки пользователя на push-уведомления. Это логика JavaScript, которая нужна пользовательскому интерфейсу вашего веб-приложения, чтобы позволить пользователю регистрироваться для отправки сообщений.
- Отправка push-сообщения - реализация вызова API на вашем сервере, который отправляет push-сообщение на устройство пользователя.
- Получение push-сообщения - обработка push-сообщения после его поступления в браузер.
Теперь опишем весь процесс более подробно.
Обнаружение поддержки браузера
Во-первых, нам нужно проверить, поддерживает ли текущий браузер push-сообщения. Мы можем проверить, поддерживается ли push, двумя простыми проверками:
- Проверьте
serviceWorker
на объектеnavigator
- Проверьте
PushManager
на объектеwindow
Обе проверки выглядят так:
Зарегистрировать сервис-воркера
На данный момент мы знаем, что эта функция поддерживается. Следующим шагом является регистрация нашего сервис-воркера.
Регистрация Service Worker - это то, с чем вы должны быть уже знакомы из предыдущего нашего поста.
Запрос разрешения
После регистрации Service Worker мы можем приступить к подписке пользователя. Для этого нам нужно получить его разрешение на отправку ему push-сообщений.
API для получения разрешения относительно прост, однако недостатком является то, что API изменился с приема обратного вызова на возврат обещания. Это создает проблему: мы не можем сказать, какая версия API реализована в текущем браузере, поэтому вам необходимо реализовать и обработать оба.
Выглядит это примерно так:
Вызов Notification.requestPermission()
отобразит пользователю следующую подсказку:
После того, как разрешение было предоставлено, закрыто или заблокировано, мы получим результат в виде строки: ‘granted’
, ‘default’
или ‘denied’
.
Имейте в виду, что если пользователь нажмет кнопку Block
, ваше веб-приложение не сможет снова запросить разрешение у пользователя, пока он вручную не «разблокирует» ваше приложение, изменив состояние разрешения. Эта опция похоронена в панели настроек.
Подписка пользователя с помощью PushManager
После регистрации нашего сервисного работника и получения разрешения мы можем подписать пользователя, позвонив по номеру registration.pushManager.subscribe()
, когда вы зарегистрируете своего сервисного работника.
Весь фрагмент может выглядеть так (включая регистрацию Service Worker):
registration.pushManager.subscribe(options)
принимает объект options, который состоит как из обязательных, так и из дополнительных параметров:
- userVisibleOnly: логическое значение, указывающее, что возвращенная push-подписка будет использоваться только для сообщений, эффект которых становится видимым для пользователя. Его необходимо установить на
true
, иначе вы получите сообщение об ошибке (для этого есть исторические причины). - applicationServerKey:
DOMString
илиArrayBuffer
в кодировке Base64, содержащий открытый ключ, который push-сервер будет использовать для аутентификации вашего сервера приложений.
Вашему серверу необходимо сгенерировать пару ключей сервера приложений - они также известны как ключи VAPID, которые уникальны для вашего сервера. Это пара открытого и закрытого ключей. Закрытый ключ секретно хранится на вашей стороне, а открытый ключ обменивается с клиентом. Ключи позволяют push-сервису узнать, какой сервер приложений подписал пользователя, и убедиться, что это тот же сервер, который отправляет push-сообщения этому конкретному пользователю.
Вам нужно создать пару закрытого / открытого ключей только один раз для вашего приложения. Один из способов сделать это - перейти на https://web-push-codelab.glitch.me/.
Браузер передает applicationServerKey
(общедоступный) в службу push-уведомлений при подписке пользователя, что означает, что служба push может связать открытый ключ вашего приложения с PushSubscription
пользователя.
Вот что происходит:
- Ваше веб-приложение загружено, и вы вызываете
subscribe()
, передавая ключ сервера. - Браузер делает сетевой запрос к службе push, которая сгенерирует конечную точку, свяжет эту конечную точку с ключом и вернет конечную точку браузеру.
- Браузер добавит эту конечную точку к объекту
PushSubscription
, который возвращается через обещаниеsubscribe()
.
Позже, когда вы захотите отправить push-сообщение, вам нужно будет создать Заголовок авторизации, который будет содержать информацию, подписанную закрытым ключом вашего сервера приложений. Когда служба push получает запрос на отправку push-сообщения, она проверяет заголовок, просматривая открытый ключ, который он уже связал с этой конкретной конечной точкой (второй шаг).
Объект PushSubscription
PushSubscription
содержит всю информацию, необходимую для отправки push-сообщения на устройство пользователя. Вот как это выглядит:
{
"endpoint": "https://domain.pushservice.com/some-id",
"keys": {
"p256dh":
"BIPUL12DLfytvTajnryr3PJdAgXS3HGMlLqndGcJGabyhHheJYlNGCeXl1dn18gSJ1WArAPIxr4gK0_dQds4yiI=",
"auth":"FPssMOQPmLmXWmdSTdbKVw=="
}
}
endpoint
- это URL-адрес службы push-уведомлений. Чтобы инициировать push-сообщение, отправьте POST-запрос на этот URL-адрес.
Объект keys
содержит значения, используемые для шифрования данных сообщения, отправленного с push-сообщением.
Как только пользователь подписан и у вас есть PushSubscription
, вам нужно отправить его на свой сервер. Там (на сервере) вы сохраните подписку в базе данных и отныне будете использовать ее для отправки push-сообщений этому пользователю.
Отправка push-сообщения
Когда вы хотите отправить своим пользователям push-сообщение, первое, что вам нужно, - это push-сервис. Вы сообщаете службе push (через вызов API), какие данные отправлять, кому отправлять сообщение и какие критерии о том, как отправить сообщение. Обычно этот вызов API выполняется с вашего сервера.
Push-сервисы
Служба push - это служба, которая принимает запросы, проверяет их и доставляет push-сообщение в соответствующий браузер.
Обратите внимание, что служба push не управляется вами - это сторонняя служба. Ваш сервер - это тот, который связывается с push-сервисом через API. Примером службы push-уведомлений является Google FCM.
Служба толкания берет на себя всю тяжелую работу. Например, если браузер находится в автономном режиме, служба push-уведомлений будет ставить сообщения в очередь и ждать, пока браузер снова не подключится к сети, прежде чем отправлять соответствующее сообщение.
Каждый браузер может использовать любую службу push-уведомлений, которую он хочет, и это не зависит от разработчика.
Однако все push-сервисы имеют одни и те же API, поэтому это не создает трудностей при реализации.
Чтобы получить URL-адрес, который будет обрабатывать запросы ваших push-сообщений, вам необходимо проверить сохраненное значение endpoint
в объекте PushSubscription
.
Push Service API
API службы push-уведомлений позволяет отправлять сообщения пользователю. API - это протокол Web Push, который является стандартом IETF, который определяет, как вы делаете вызов API для службы push.
Данные, которые вы отправляете с помощью push-сообщения, должны быть зашифрованы. Таким образом, вы не позволяете push-сервисам просматривать отправленные данные. Это важно, потому что браузер - это тот, который решает, какую службу push использовать (и он может использовать некоторую ненадежную и недостаточно безопасную службу push).
Для каждого push-сообщения вы также можете дать следующие инструкции:
- TTL - определяет, как долго сообщение должно находиться в очереди, прежде чем оно будет удалено и не доставлено.
- Приоритет - определяет приоритет каждого сообщения, что позволит службе push отправлять только сообщения с высоким приоритетом, если необходимо сохранить заряд батареи пользовательского устройства.
- Тема - присваивает push-сообщению название темы, которое заменяет ожидающие сообщения на ту же тему, чтобы после включения устройства пользователь не получал устаревшую информацию.
Push событие в браузере
После того, как вы отправите сообщение в службу push-уведомлений, как описано выше, сообщение будет находиться в состоянии ожидания, пока не произойдет одно из следующих событий:
- Устройство переходит в оперативный режим.
- Сообщение истекает в очереди из-за TTL.
Когда служба push доставит сообщение, браузер получит его, расшифрует и отправит событие push
в ваш Service Worker.
Самое замечательное здесь то, что браузер может выполнять вашего Service Worker, даже когда ваша веб-страница не открыта. Происходит следующее:
- Push-сообщение поступает в браузер, который его расшифровывает.
- Браузер будит Service Worker
- Событие
push
отправляется Service Worker
Код для настройки прослушивателя событий push должен быть очень похож на любой другой прослушиватель событий, который вы пишете на JavaScript:
Одна из вещей, которые следует понимать в отношении Service Workers, заключается в том, что у вас мало контроля над временем выполнения кода Service Workers. Браузер решает, когда его разбудить, а когда прекратить.
В Service Workers event.waitUntil(promise)
сообщает браузеру, что работа продолжается до тех пор, пока обещание не будет выполнено, и он не должен останавливать работника службы, если он хочет, чтобы эта работа была завершена.
Вот пример обработки события push
:
Вызов self.registration.showNotification()
отображает уведомление для пользователя и возвращает обещание, которое разрешится после отображения уведомления.
Метод showNotification(title, options)
можно визуально настроить в соответствии с вашими потребностями. Параметр title
- это string
, а параметр - это объект, который выглядит следующим образом:
{
"//": "Visual Options",
"body": "<String>",
"icon": "<URL String>",
"image": "<URL String>",
"badge": "<URL String>",
"vibrate": "<Array of Integers>",
"sound": "<URL String>",
"dir": "<String of 'auto' | 'ltr' | 'rtl'>",
"//": "Behavioural Options",
"tag": "<String>",
"data": "<Anything>",
"requireInteraction": "<boolean>",
"renotify": "<Boolean>",
"silent": "<Boolean>",
"//": "Both Visual & Behavioural Options",
"actions": "<Array of Strings>",
"//": "Information Option. No visual affect.",
"timestamp": "<Long>"
}
Более подробно о том, что делает каждый параметр, можно прочитать здесь - https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerRegistration/showNotification.
Push-уведомления могут быть отличным способом привлечь внимание пользователей, когда есть срочная, важная и своевременная информация, которой вы хотели бы поделиться с ними.
Например, мы в SessionStack планируем использовать push-уведомления, чтобы наши пользователи знали, когда в их продукте происходит сбой, проблема или аномалия. Это позволит нашим пользователям немедленно узнать, что что-то не так. Затем они могут воспроизвести проблему в виде видео и увидеть все, что произошло с их конечным пользователем, используя данные, которые были собраны нашей библиотекой, такие как изменения DOM, взаимодействия с пользователем, сетевые запросы, необработанные исключения и сообщения отладки.
Эта функция не только поможет нашим пользователям понять и воспроизвести любую проблему, но также позволит клиентам получать уведомления, как только это произойдет.
Есть бесплатный план, если вы хотите попробовать SessionStack.
Ресурсы
- Https://developers.google.com/web/fundamentals/push-notifications/
- Https://developers.google.com/web/fundamentals/push-notifications/how-push-works
- Https://developers.google.com/web/fundamentals/push-notifications/subscribing-a-user
- Https://developers.google.com/web/fundamentals/push-notifications/handling-messages