当前位置: 移动技术网 > IT编程>网页制作>CSS > ServiceWorker消息推送教程

ServiceWorker消息推送教程

2019年02月26日  | 移动技术网IT编程  | 我要评论

36uc万能登陆器,k818次列车时刻表,无限挑战130525

    pwa资料整理(三):service worker 消息推送

    pwa资料整理(三):service worker 消息推送

    系列链接消息推送消息推送整体架构消息推送具体流程参考资料

    本篇是 pwa 资料整理的第三篇,主要介绍 service worker 所实现的消息推送相关内容。

    系列链接

    manifest 添加到桌面 service worker 离线缓存 service worker 消息推送(本篇)

    消息推送

    说到消息推送就想到 http2 push。实际上 http2 push 就是一个缓存相关的机制,与消息推送没有关联。
    拓展资料:http/2 push is tougher than i thought(我之前的博客中也有对该文章的理解,如果懒得看英文原文的话可以直接看我的内容概括)。

    事实上,同 sw 实现的消息推送一样,sw 本身仅仅是提供类似 web worker 的功能,需要结合 cache api 才能实现离线缓存功能。使用 sw 实现消息推送需结合 notification api,具体功能就不介绍,可以查看 mdn 文档。

    消息推送整体架构

    消息推送看起来似乎很简单,就是服务端给客户端发送消息这样简单粗暴的东西嘛,其实并不是。
    实际上,服务端无法直接给客户端发送消息,而必须借助 push service 进行消息的推送。webpush 的整体架构如下图所示:
    webpush 架构
    这里的 ua 即 user agent,也就是用户代理;application server 为应用的服务端;push service 也就是推送服务,指的是 google 的 fcm (以前叫 gcm),或者 apple 的 apns(苹果现在还不支持 webpush)等。

    消息推送具体流程

    在使用消息推送之前,客户端需要通过 sw 进行消息订阅:

    同样是在注册 service worker 时,先通过 pushmanager.getsubscription方法获取当前客户端是否已经订阅过了,没有订阅则需要对推送订阅对象进行生成; 在向 push server 发送请求(pushmanager.subsribe)之前,已经生成了一个推送订阅对象; 得到响应之后,客户端会将推送服务生成的地址(end point)加入这个推送订阅对象中; 之后,客户端将推送订阅对象发送给服务端。

    一个完整的推送订阅对象数据结构如下:

    {
        "endpoint": "https://fcm.googleapis.com/fcm/send/...",
        "keys": {
            "p256dh" : "bncrd...",
            "auth"   : "tbhi..."
        }
    }
    

    注意:订阅信息会过期,所以不要忘了在 servier worker 中监听 pushsubscriptionchange事件,当订阅过期后自动重新订阅。

    sw 可以通过监听 push 事件来获取服务端所推送的消息。并通过 registration.shownotification方法显示消息。
    参考代码如下所示:

    // service-worker.js
    // ...
    const onpush = function(event) {
        event.waituntil(_self.registration.shownotification('new post arrival', {
            icon: '/logo.png'
        }));
    };
    
    _self.addeventlistener('push', onpush);
    

    服务端需要 push 消息时,只需要向用户订阅信息中的 url post 消息内容就行了,具体的消息分发由 push server 代为实现。服务端代码如下:

    // publish.js
    // ...
        .post('/broadcast', async ctx => {
            await readendpoints()
                .then(endpoints => {
                    ctx.status = 200;
                    ctx.body = {};
    
                    endpoints.foreach(endpoint => {
                        webpush.sendnotification({ endpoint })
                            .catch(console.error);
                    });
                })
                .catch(err => {
                    ctx.status = 500;
                    ctx.body = err;
                });
        });
    

    在消息推送的过程中,必不可免的存在一些安全性相关的问题,不过这些都交由 push server 完成,开发者只需要关心客户端和服务端就可以了。需要注意的是:浏览器关闭时,sw 的线程会被回收,也就意味着消息无法接收。

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网