Push-уведомления представляют собой механизм отправки сообщений пользователю даже при закрытом веб-приложении. В контексте Riot.js, как и в других современных фреймворках, интеграция push-уведомлений требует взаимодействия с Service Workers, Push API и Notification API браузера.
Для работы с push-уведомлениями необходим Service Worker. Он регистрируется в основном JavaScript-файле приложения:
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/service-worker.js')
.then(registration => {
console.log('Service Worker зарегистрирован с областью:', registration.scope);
})
.catch(error => {
console.error('Ошибка регистрации Service Worker:', error);
});
}
Ключевые моменты:
После регистрации Service Worker необходимо получить разрешение от пользователя на получение уведомлений и подписаться на push-сервис:
async function subscribeUser() {
const registration = await navigator.serviceWorker.ready;
try {
const subscription = await registration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: urlBase64ToUint8Array('<VAPID_PUBLIC_KEY>')
});
console.log('Подписка выполнена:', subscription);
// Отправка данных подписки на сервер
await fetch('/api/save-subscription', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(subscription)
});
} catch (err) {
console.error('Ошибка подписки на Push:', err);
}
}
Важные моменты:
userVisibleOnly: true гарантирует, что уведомления
будут видимыми пользователю.applicationServerKey — публичный ключ VAPID для
безопасного взаимодействия с push-сервером.Service Worker получает push-события даже при закрытой вкладке:
self.addEventListener('push', event => {
const data = event.data.json();
const options = {
body: data.body,
icon: data.icon,
badge: data.badge,
data: { url: data.url }
};
event.waitUntil(
self.registration.showNotification(data.title, options)
);
});
Особенности:
event.data.json() позволяет извлечь данные уведомления,
отправленные сервером.body, icon,
badge) определяют визуальное оформление.data.url может использоваться для перехода на
определённую страницу при клике.Для перенаправления пользователя при клике по уведомлению необходимо добавить обработчик:
self.addEventListener('notificationclick', event => {
event.notification.close();
event.waitUntil(
clients.matchAll({ type: 'window', includeUncontrolled: true }).then(clientList => {
if (clients.openWindow) {
return clients.openWindow(event.notification.data.url);
}
})
);
});
Важные моменты:
event.notification.close())
предотвращает его висение на экране.clients.matchAll позволяет найти уже открытые окна и
избежать создания дубликатов.Riot.js предоставляет реактивную систему для обновления интерфейса. Можно связывать push-уведомления с состоянием компонентов:
<notification-list>
<ul>
<li each={notifications}>{message}</li>
</ul>
<script>
export default {
notifications: [],
addNotification(data) {
this.notifications.push(data);
this.update();
}
}
</script>
</notification-list>
addNotification через глобальный EventBus или через
WebSocket-соединение.Для отправки уведомлений сервер использует подписку пользователя и
VAPID-ключи. Пример на Node.js с использованием библиотеки
web-push:
const webpush = require('web-push');
webpush.setVapidDetails(
'mailto:admin@example.com',
'<VAPID_PUBLIC_KEY>',
'<VAPID_PRIVATE_KEY>'
);
const pushSubscription = {/* данные подписки пользователя */};
const payload = JSON.stringify({
title: 'Новое уведомление',
body: 'У вас новое сообщение',
icon: '/icon.png',
url: '/messages'
});
webpush.sendNotification(pushSubscription, payload)
.then(response => console.log('Уведомление отправлено', response))
.catch(error => console.error('Ошибка отправки уведомления', error));
Особенности:
Push-уведомления в Riot.js позволяют создавать реактивные интерфейсы, которые остаются интерактивными даже при закрытом приложении, обеспечивая современный уровень взаимодействия с пользователем.