О практической работе
1. Обзор
Push-сообщения обеспечивают простой и эффективный способ повторного взаимодействия с вашими пользователями. В этой лаборатории кода вы узнаете, как добавлять push-уведомления в свое веб-приложение.
Что вы узнаете
- Как подписаться и отписаться пользователя на push-рассылку
- Как обрабатывать входящие push-сообщения
- Как отобразить уведомление
- Как реагировать на клики по уведомлениям
Что вам понадобится
- Chrome 52 или выше
- Веб-сервер для Chrome или ваш собственный веб-сервер по выбору
- Текстовый редактор
- Базовые знания HTML, CSS, JavaScript и Chrome DevTools.
- Пример кода (см. раздел «Настройка»).
2. Настроить
Загрузите пример кода
Получить пример кода для этой лаборатории кода можно двумя способами:
- Клонируйте репозиторий Git:
git clone https://github.com/GoogleChrome/push-notifications.git
- Загрузите ZIP-файл:
Если вы загрузите исходный код в виде ZIP-файла, при его распаковке вы получите корневую папку push-notifications-master
.
Установите и проверьте веб-сервер
Хотя вы можете использовать собственный веб-сервер, эта лаборатория кода разработана для хорошей работы с приложением «Веб-сервер для Chrome». Если это приложение еще не установлено, его можно загрузить из Интернет-магазина Chrome:
После установки приложения «Веб-сервер для Chrome» нажмите ярлык «Приложения» на панели закладок:
В окне «Приложения» щелкните значок «Веб-сервер»:
Далее вы увидите это диалоговое окно, которое позволит вам настроить локальный веб-сервер:
Нажмите кнопку «Выбрать папку» и выберите папку app
в загруженной папке push-notifications
. Это позволяет вам обслуживать незавершенную работу через URL-адрес, указанный в разделе URL-адреса веб-сервера диалогового окна.
В разделе «Параметры» установите флажок «Автоматически показывать index.html» , как показано ниже:
Затем остановите и перезапустите сервер, сдвинув переключатель «Веб-сервер: НАЧАЛО» влево, а затем обратно вправо.
Щелкните URL-адрес веб-сервера, чтобы посетить ваш сайт в веб-браузере. Вы должны увидеть страницу, которая выглядит следующим образом — хотя в вашей версии в качестве адреса может отображаться 127.0.0.1:8887:
Всегда обновляйте сервис-воркера
Во время разработки полезно следить за тем, чтобы ваш сервис-воркер всегда был в курсе последних изменений.
Чтобы настроить это в Chrome:
- Перейдите на вкладку Push Codelab .
- Откройте DevTools: Ctrl-Shift-I в Windows и Linux, Cmd-Option-I в macOS.
- Выберите панель «Приложения» , перейдите на вкладку «Сервисные работники» и установите флажок «Обновлять при перезагрузке» . Если этот флажок установлен, сервис-воркер принудительно обновляется каждый раз при перезагрузке страницы.
3. Зарегистрируйте сервисного работника
Обратите внимание, что в каталоге вашего app
есть пустой файл с именем sw.js
Этот файл будет вашим сервис-воркером. Пока он может оставаться пустым. Вы добавите к нему код позже.
Во-первых, вам необходимо зарегистрировать этот файл в качестве вашего сервис-воркера.
Ваша страница app/index.html
загружает scripts/main.js
. Вы регистрируете своего сервис-воркера в этом файле JavaScript.
Добавьте следующий код в scripts/main.js
:
if ('serviceWorker' in navigator && 'PushManager' in window) {
console.log('Service Worker and Push are supported');
navigator.serviceWorker.register('sw.js')
.then(function(swReg) {
console.log('Service Worker is registered', swReg);
swRegistration = swReg;
})
.catch(function(error) {
console.error('Service Worker Error', error);
});
} else {
console.warn('Push messaging is not supported');
pushButton.textContent = 'Push Not Supported';
}
Этот код проверяет, поддерживаются ли вашим браузером сервисные работники и push-сообщения. Если они поддерживаются, код регистрирует ваш файл sw.js
Попробуйте это
Проверьте свои изменения, обновив вкладку Push Codelab в браузере.
Проверьте консоль в Chrome DevTools на Service Worker is registered message
, например:
Получить ключи сервера приложений
Для работы с этой кодовой лабораторией вам необходимо сгенерировать ключи сервера приложений. Вы можете сделать это на сопутствующем сайте: web-push-codelab.glitch.me.
Здесь вы можете сгенерировать пару открытого и закрытого ключей.
Скопируйте свой открытый ключ в scripts/main.js
заменив значение <Your Public Key>
:
const applicationServerPublicKey = '<Your Public Key>';
Важно: никогда не следует помещать свой закрытый ключ в свое веб-приложение!
4. Инициализировать состояние
На данный момент кнопка «Включить » веб-приложения отключена, и ее нельзя нажать. Это связано с тем, что хорошей практикой является отключить кнопку по умолчанию и включить ее после того, как вы узнаете, что push-сообщения поддерживаются браузером, и вы сможете проверить, подписан ли пользователь в настоящее время на рассылку сообщений или нет.
Вам нужно будет создать две функции в scripts/main.js
:
-
initializeUI
, чтобы проверить, подписан ли пользователь в данный момент -
updateBtn
, чтобы включить вашу кнопку и изменить текст в зависимости от того, подписан пользователь или нет
Добавьте функцию initializeUI
в main.js
следующим образом:
function initializeUI() {
// Set the initial subscription value
swRegistration.pushManager.getSubscription()
.then(function(subscription) {
isSubscribed = !(subscription === null);
if (isSubscribed) {
console.log('User IS subscribed.');
} else {
console.log('User is NOT subscribed.');
}
updateBtn();
});
}
Ваш новый метод использует swRegistration
из предыдущего шага, получает из него свойство pushManager
и вызывает для него getSubscription()
.
pushManager
. getSubscription()
возвращает обещание, которое разрешается с текущей подпиской, если таковая имеется. В противном случае он возвращает null
. Благодаря этому вы можете проверить, подписан ли уже пользователь, установить значение isSubscribed
, а затем вызвать updateBtn()
чтобы обновить кнопку.
Добавьте функцию updateBtn()
в main.js
:
function updateBtn() {
if (isSubscribed) {
pushButton.textContent = 'Disable Push Messaging';
} else {
pushButton.textContent = 'Enable Push Messaging';
}
pushButton.disabled = false;
}
Эта функция включает кнопку и меняет текст кнопки в зависимости от того, подписан пользователь или нет.
Последнее, что нужно сделать, это вызвать initializeUI()
, когда ваш сервис-воркер зарегистрирован в main.js
:
navigator.serviceWorker.register('sw.js')
.then(function(swReg) {
console.log('Service Worker is registered', swReg);
swRegistration = swReg;
initializeUI();
})
Попробуйте это
Обновите вкладку Push Codelab . Вы должны увидеть, что кнопка «Включить push-сообщения» теперь включена (вы можете нажать ее), и вы должны увидеть, что User is NOT subscribed
в консоли.
По мере прохождения оставшейся части этой кодовой лаборатории вы должны видеть, что текст кнопки меняется каждый раз, когда вы подписываетесь или отписываетесь.
5. Подписаться на пользователя
На данный момент кнопка «Включить push-сообщения» мало что делает. Давайте это исправим.
В функции initializeUI()
добавьте прослушиватель кликов для вашей кнопки:
function initializeUI() {
pushButton.addEventListener('click', function() {
pushButton.disabled = true;
if (isSubscribed) {
// TODO: Unsubscribe user
} else {
subscribeUser();
}
});
// Set the initial subscription value
swRegistration.pushManager.getSubscription()
.then(function(subscription) {
isSubscribed = !(subscription === null);
updateSubscriptionOnServer(subscription);
if (isSubscribed) {
console.log('User IS subscribed.');
} else {
console.log('User is NOT subscribed.');
}
updateBtn();
});
}
Когда пользователь нажимает кнопку, вы отключаете кнопку, чтобы убедиться, что пользователь не сможет нажать ее второй раз, поскольку подписка на push-сообщения может занять некоторое время.
Затем вы вызываете subscribeUser()
если пользователь в данный момент не подписан. Для этого вам нужно вставить следующий код в scripts/main.js
:
function subscribeUser() {
const applicationServerKey = urlB64ToUint8Array(applicationServerPublicKey);
swRegistration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: applicationServerKey
})
.then(function(subscription) {
console.log('User is subscribed.');
updateSubscriptionOnServer(subscription);
isSubscribed = true;
updateBtn();
})
.catch(function(error) {
console.error('Failed to subscribe the user: ', error);
updateBtn();
});
}
Давайте рассмотрим, что делает этот код и как он подписывает пользователя на push-сообщения.
Сначала вы берете открытый ключ сервера приложений, который закодирован для URL-адресов Base64 , и преобразуете его в UInt8Array
, поскольку это ожидаемый входной сигнал вызова subscribe()
. Функция urlB64ToUint8Array()
находится в верхней части scripts/main.js
.
После преобразования значения вы вызываете метод subscribe()
в pushManager
вашего сервис-воркера, передавая открытый ключ вашего сервера приложений и значение userVisibleOnly: true
.
const applicationServerKey = urlB64ToUint8Array(applicationServerPublicKey);
swRegistration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: applicationServerKey
})
Параметр userVisibleOnly
гарантирует, что вы будете показывать уведомление каждый раз при отправке push-сообщения. В настоящее время это значение является обязательным и должно быть истинным.
Вызов subscribe()
возвращает обещание, которое будет разрешено после следующих шагов:
- Пользователь предоставил разрешение на отображение уведомлений.
- Браузер отправил сетевой запрос в службу push-уведомлений, чтобы получить данные, необходимые для создания
PushSubscription
.
Обещание subscribe()
будет разрешено с помощью PushSubscription
, если эти шаги были успешными. Если пользователь не предоставит разрешение или возникнут какие-либо проблемы с подпиской пользователя, обещание будет отклонено с ошибкой. Это дает вам следующую цепочку обещаний в вашей кодовой лаборатории:
swRegistration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: applicationServerKey
})
.then(function(subscription) {
console.log('User is subscribed.');
updateSubscriptionOnServer(subscription);
isSubscribed = true;
updateBtn();
})
.catch(function(err) {
console.log('Failed to subscribe the user: ', err);
updateBtn();
});
При этом вы либо получаете подписку и считаете пользователя подписанным, либо ловите ошибку и регистрируете ее в консоли. В обоих сценариях вы вызываете updateBtn()
чтобы убедиться, что кнопка снова включена и имеет соответствующий текст.
В реальном приложении функция updateSubscriptionOnServer()
позволяет отправлять данные о подписке на серверную часть, но для лаборатории кода вы просто отображаете подписку в своем пользовательском интерфейсе. Добавьте следующую функцию в scripts/main.js
:
function updateSubscriptionOnServer(subscription) {
// TODO: Send subscription to application server
const subscriptionJson = document.querySelector('.js-subscription-json');
const subscriptionDetails =
document.querySelector('.js-subscription-details');
if (subscription) {
subscriptionJson.textContent = JSON.stringify(subscription);
subscriptionDetails.classList.remove('is-invisible');
} else {
subscriptionDetails.classList.add('is-invisible');
}
}
Попробуйте это
Перейдите на вкладку Push Codelab , обновите страницу и нажмите кнопку. Вы должны увидеть запрос на разрешение, подобный этому:
Если вы дадите разрешение, вы должны увидеть, User is subscribed
и вошёл в консоль. Текст кнопки изменится на «Отключить push-сообщения» , и вы сможете просмотреть подписку в виде данных JSON внизу страницы.
6. Разрешение на обработку отклонено
Одна вещь, которую вы еще не рассмотрели, — это то, что произойдет, если пользователь заблокирует запрос на разрешение. Это требует особого внимания, поскольку если пользователь заблокирует разрешение, ваше веб-приложение не сможет повторно отобразить запрос на разрешение и не сможет подписаться на пользователя. Вам нужно как минимум отключить кнопку, чтобы пользователь знал, что ее нельзя использовать.
Очевидное место для реализации этого сценария — функция updateBtn()
. Все, что вам нужно сделать, это проверить значение Notification.permission
, например:
function updateBtn() {
if (Notification.permission === 'denied') {
pushButton.textContent = 'Push Messaging Blocked';
pushButton.disabled = true;
updateSubscriptionOnServer(null);
return;
}
if (isSubscribed) {
pushButton.textContent = 'Disable Push Messaging';
} else {
pushButton.textContent = 'Enable Push Messaging';
}
pushButton.disabled = false;
}
Вы знаете, что если в разрешении denied
, пользователь не сможет подписаться, и вы больше ничего не сможете сделать, поэтому лучшим подходом является постоянное отключение кнопки.
Попробуйте это
Поскольку вы уже предоставили разрешение для своего веб-приложения на предыдущем шаге, вам нужно щелкнуть i в кружке в строке URL-адреса и изменить разрешение «Уведомления» на «Использовать глобальное значение по умолчанию» (Спросить) .
После изменения этого параметра обновите страницу, нажмите кнопку «Включить push-сообщения» и выберите «Блокировать» в диалоговом окне разрешений. Кнопка будет отключена, и на ней будет отображаться текст Push-сообщения заблокированы .
Благодаря этому изменению вы теперь можете подписаться на пользователя, позаботившись о возможных сценариях разрешений.
7. Обработка push-события
Прежде чем вы узнаете, как отправить push-сообщение из вашего бэкэнда, вам необходимо подумать, что на самом деле произойдет, когда подписанный пользователь получит push-сообщение.
Когда вы запускаете push-сообщение, браузер получает push-сообщение, определяет, для какого работника службы оно предназначено, пробуждает этого работника службы и отправляет событие push. Вам необходимо прослушать это событие и в результате отобразить уведомление.
Добавьте следующий код в файл sw.js
:
self.addEventListener('push', function(event) {
console.log('[Service Worker] Push Received.');
console.log(`[Service Worker] Push had this data: "${event.data.text()}"`);
const title = 'Push Codelab';
const options = {
body: 'Yay it works.',
icon: 'images/icon.png',
badge: 'images/badge.png'
};
event.waitUntil(self.registration.showNotification(title, options));
});
Давайте пройдемся по этому коду. Вы прослушиваете push
события в своем сервис-воркере, добавляя прослушиватель событий:
self.addEventListener('push', ... );
(Если вы раньше не играли с веб-воркерами, self
, вероятно, является новым. В файле сервисного работника self
ссылается на самого сервисного работника.)
При получении push-сообщения будет вызван прослушиватель событий, и вы создадите уведомление, вызвав showNotification()
в registration
свойстве сервисного работника. showNotification()
требует title
; вы также можете предоставить ему объект options
, чтобы установить основное сообщение, значок и значок. (На момент написания значок использовался только на Android.)
const title = 'Push Codelab';
const options = {
body: 'Yay it works.',
icon: 'images/icon.png',
badge: 'images/badge.png'
};
self.registration.showNotification(title, options);
Последнее, что нужно учитывать при обработке push
событий, — это event.waitUntil()
. Этот метод принимает обещание, позволяющее браузеру поддерживать работу вашего сервис-воркера до тех пор, пока переданное обещание не будет выполнено.
Чтобы сделать приведенный выше код немного проще для понимания, вы можете переписать его так:
const notificationPromise = self.registration.showNotification(title, options);
event.waitUntil(notificationPromise);
Теперь, когда вы прошли через событие push, давайте проверим его.
Попробуйте это
Благодаря обработке push-событий в сервис-воркере вы можете запустить ложное push-событие, чтобы проверить, что происходит при получении сообщения.
В своем веб-приложении подпишитесь на push-сообщения и убедитесь, что в консоли User IS subscribed
. На панели приложений в DevTools на вкладке Service Workers нажмите кнопку «Нажать» :
После того, как вы нажмете «Push» , вы должны увидеть такое уведомление:
Примечание. Если этот шаг не сработал, попробуйте отменить регистрацию вашего сервисного работника с помощью ссылки «Отменить регистрацию» на панели приложений DevTools, дождитесь остановки сервисного работника, а затем перезагрузите страницу.
8. Нажмите на уведомление
Если вы нажмете одно из этих уведомлений, вы заметите, что ничего не происходит. Вы можете обрабатывать клики уведомлений, прослушивая события notificationclick
в своем сервисном работнике.
Начните с добавления прослушивателя notificationclick
в sw.js
:
self.addEventListener('notificationclick', function(event) {
console.log('[Service Worker] Notification click received.');
event.notification.close();
event.waitUntil(
clients.openWindow('https://developers.google.com/web')
);
});
Когда пользователь щелкает уведомление, будет вызван прослушиватель событий notificationclick
.
Код сначала закрывает уведомление, по которому было нажато:
event.notification.close();
Затем открывается новое окно или вкладка с загрузкой URL-адреса https://developers.google.com/web
. Не стесняйтесь изменить это.
event.waitUntil(
clients.openWindow('https://developers.google.com/web/')
);
event.waitUntil()
гарантирует, что браузер не завершит работу сервис-воркера до того, как будет отображено новое окно или вкладка.
Попробуйте это
Попробуйте еще раз вызвать push-сообщение в DevTools и щелкните уведомление. Теперь вы увидите закрытие уведомления и открытие новой вкладки.
9. Отправляйте push-сообщения
Вы видели, что ваше веб-приложение способно отображать уведомление с помощью DevTools, и узнали, как закрыть уведомление одним щелчком мыши. Следующим шагом является отправка фактического push-сообщения.
Обычно для этого требуется отправить подписку с веб-страницы на серверную часть. Затем серверная часть инициирует push-сообщение, выполнив вызов API к конечной точке подписки.
Это выходит за рамки данной лаборатории кода, но вы можете использовать сопутствующий сайт ( web-push-codelab.glitch.me ), чтобы вызвать фактическое push-сообщение. Вставьте подписку внизу страницы:
Затем вставьте это на сопутствующий сайт в текстовую область «Подписка на отправку» :
В разделе «Текст для отправки» добавьте любую строку, которую хотите отправить вместе с push-сообщением.
Нажмите кнопку «Отправить push-сообщение» .
После этого вы должны получить push-сообщение. Использованный вами текст будет записан в консоль.
Это должно дать вам возможность протестировать отправку и получение данных и, как результат, манипулировать уведомлениями.
Сопутствующее приложение — это всего лишь узел-сервер, который использует библиотеку веб-push для отправки сообщений. Стоит просмотреть организацию web-push-libs на GitHub, чтобы узнать, какие библиотеки доступны для отправки вам push-сообщений. Это обрабатывает множество деталей для запуска push-сообщений.
Вы можете увидеть весь код сопутствующего сайта здесь .
10. Отписаться от пользователя
Единственное, чего не хватает, — это возможности отписать пользователя от push-уведомлений. Для этого вам нужно вызвать unsubscribe()
в PushSubscription
.
Вернувшись в файл scripts/main.js
, измените прослушиватель кликов pushButton
в initializeUI()
на следующее:
pushButton.addEventListener('click', function() {
pushButton.disabled = true;
if (isSubscribed) {
unsubscribeUser();
} else {
subscribeUser();
}
});
Обратите внимание, что теперь вы собираетесь вызвать новую функцию unsubscribeUser()
. В этой функции вы получаете текущую подписку и вызываете для нее unsubscribe()
. Добавьте следующий код в scripts/main.js
:
function unsubscribeUser() {
swRegistration.pushManager.getSubscription()
.then(function(subscription) {
if (subscription) {
return subscription.unsubscribe();
}
})
.catch(function(error) {
console.log('Error unsubscribing', error);
})
.then(function() {
updateSubscriptionOnServer(null);
console.log('User is unsubscribed.');
isSubscribed = false;
updateBtn();
});
}
Давайте пройдемся по этой функции.
Сначала вы получаете текущую подписку, вызывая getSubscription()
:
swRegistration.pushManager.getSubscription()
Это возвращает обещание, которое разрешается с помощью PushSubscription
, если таковое существует; в противном случае возвращается null
. Если есть подписка, вы вызываете для нее unsubscribe()
, что делает PushSubscription
недействительным.
swRegistration.pushManager.getSubscription()
.then(function(subscription) {
if (subscription) {
// TODO: Tell application server to delete subscription
return subscription.unsubscribe();
}
})
.catch(function(error) {
console.log('Error unsubscribing', error);
})
Вызов unsubscribe()
возвращает обещание, поскольку его выполнение может занять некоторое время. Вы возвращаете это обещание, поэтому следующий then()
в цепочке ожидает завершения unsubscribe()
. Вы также добавляете обработчик catch на случай, если вызов unsubscribe()
приведет к ошибке. После этого вы можете обновить свой пользовательский интерфейс.
.then(function() {
updateSubscriptionOnServer(null);
console.log('User is unsubscribed.');
isSubscribed = false;
updateBtn();
})
Попробуйте это
У вас должна быть возможность нажать «Включить push-сообщения» или «Отключить push-сообщения» в вашем веб-приложении, и журналы будут показывать, что пользователь подписан и отписан от подписки.
11. Законченный
Поздравляем с завершением этой лаборатории!
В этой лаборатории кода показано, как начать работу с добавлением push-уведомлений в ваше веб-приложение. Если вы хотите узнать больше о возможностях веб-уведомлений, ознакомьтесь с этими документами .
Если вы хотите разместить push-уведомления на своем сайте, вас может заинтересовать добавление поддержки старых браузеров или браузеров, не соответствующих стандартам, которые используют GCM. Узнайте больше здесь .
Дальнейшее чтение
- Веб-push-уведомление : документация по основам веб-технологий.
- Библиотеки веб-push : библиотеки веб-push, включая Node.js, PHP, Java, Python, C и C#.