推送可以在浏览器中实现和原生App中的通知一样的功能。
The Push API gives web applications the ability to receive messages pushed to them from a server, whether or not the web app is in the foreground, or even currently loaded, on a user agent. This lets developers deliver asynchronous notifications and updates to users that opt in, resulting in better engagement with timely new content.
要通过Service Worker来发送通知,需要使用HTML5的Notification API。
Notificaton的三种状态
- granted(用户同意接收通知)
- denied(用户不同意接收通知)
- default(通知时提示)
Server Push Work Flow
Push Server -> Push Service(Google) -> PWA App
应用服务器生成公私钥,客户端利用公钥,请求Google通知服务器,Google通知服务器返回Subscription Object,应用服务器利用该对象向客户端发送消息。
subscription object example
{
"endpoint": "https://fcm.googleapis.com/fcm/send/da6nAuGjSxA:APA91bGTMoI8y1UlQgvkU-xIhorpDgVzOHHw-IalL8Yyk2v1T8M6BxCz8yE8oawHJUrzNr4DXELK7sAKkrD0YUf-yOOZ4slI-RBcZx-UU5E2T-TAnzAN2-Fakm7QdGAdWJTY1OU1zQ_Q",
"expirationTime": null,
"keys": {
"p256dh": "BNBnYTHlMDZRGlNOW3ulmxoNIua94THU9QCFT0nlztuZaFU-HU8k1OR2YeK1CfQn7adBDQMw3dlQnWW9L0gPtd4",
"auth": "Krh9e8ATlfyEKKOqeGIO8A"
}
}
客户端代码及配置
请参考完整示例中scripts/main.js
和sw.js
服务器端推送程序
push-server.js
// Web-push Module
const webpush = require('web-push');
const vapid = require('./vapid.json');
// Configure keys
webpush.setVapidDetails(
'mailto:ray@stackacademy.tv',
vapid.publicKey,
vapid.privateKey
);
const pushSubscription = {
endpoint: "https://fcm.googleapis.com/fcm/send/f8dKsZEPSlA:APA91bFXvGYKwG6Ey1aPuZsISV1cJrRzCPaGkYuf6QZf_jF-uPWJrS7a60hhKc0_O7-pFVUQtW8owl_9_ex9xWHZqZhJxwf7ciSsUas6qcHBooKyB8osXVT_dVmKihm2-K1xpsg-7mlJ",
keys: {
auth: "BaoLgoJHMGnrTFHGzaCnvg",
p256dh: "BDh1-EPnFjeYqnORIls2NZCd2JpVbL1BLJ-ZaRnSf8H5_8_4dkXAKX72qrz2MMV0IYzYSWSnJA_GPCmGi6vZjQQ"
}
};
webpush.sendNotification(pushSubscription, 'A notification from the push server')
.then((res) => {
console.log(res)
})
.catch((err) => {
console.log(err)
})
console.log('Push sent to client');
发送通知
$ node push-server.js
服务器端记录用户的订阅
服务器端存储客户端生成的订阅对象,在发送时使用web-push
根据订阅对象来发送。
我实验过的完整示例
这个完整示例,包括对 向网络应用添加推送通知这篇教程的实践和web-push库的使用示例。
注意事项
发送和接收都要联通Google服务器。客户端和服务器端都要联通。