Progressive Web Apps(PWA)核心技术-Push Notifications

PWA的推送是基于Notifications API 和 Push API,Notifications API让应用程序向用户显示系统通知。 Push API允许service worker处理来自服务器的推送消息,即使应用程序处于不活动状态。

推送通知术语

  • 通知 - 在应用的普通用户界面(即浏览器)之外向用户显示的消息,
  • 推送消息 - 从服务器发送到客户端的消息
  • 推送通知 - 为响应推送消息而创建的通知
  • 通知API - 用于配置和向用户显示通知的界面
  • 推送API - 用于将您的应用程序订阅到推送服务的接口,并在服务人员中接收推送消息
  • 网络推送(Web Push) - 一个非正式的术语,指的是将消息从服务器推送到网络上的客户端所涉及的过程或组件
  • 推送服务 - 将推送消息从服务器路由到客户端的系统。 每个浏览器都实现自己的推送服务
  • Web推送协议 - 描述应用程序服务器或用户代理如何与推送服务交互
通知API

通知API有两个核心部分
1、Invocation API *控制如何使您的通知显示,包括样式和振动。
2、Interaction API *控制用户使用通知时发生的情况。

因为各个浏览器的兼容性不一致,所以我们在使用之前需要检查是否支持和是否拥有权限等。

//检查是否支持
if ('Notification' in window && navigator.serviceWorker) {
  // Display the UI to let the user toggle notifications
}
//检查权限
if (Notification.permission === "granted") { 
  /* do our magic */
} else if (Notification.permission === "blocked") {
 //用户拒绝推送 
} else {
  //显示提示
}

通知相关代码应写到主要的js文件中,比如main.js。

请求通知权限

Notification.requestPermission(function(status) {
    console.log('Notification permission status:', status);
});

显示通知
注意在service worker注册对象上调用showNotification方法。 这将在service worker上创建通知,以便由service worker监听与通知交互触发的事件。

function displayNotification() {
  if (Notification.permission == 'granted') {
    navigator.serviceWorker.getRegistration().then(function(reg) {
      reg.showNotification('Hello world!');
    });
  }
}

添加通知选项

完整选项介绍:
https://developer.mozilla.org/enUS/docs/Web/API/ServiceWorkerRegistration/showNotification
在线效果展示:
https://tests.peter.sh/notification-generator/

function displayNotification() {
  if (Notification.permission == 'granted') {
    navigator.serviceWorker.getRegistration().then(function(reg) {
      var options = {
        body: 'Here is a notification body!',//主体内容
        icon: 'images/example.png',//通知图标
        vibrate: [100, 50, 100],//震动,先100ms然后暂停50ms最后在震动100ms
        data: {//通知数据,用于人机交互
          dateOfArrival: Date.now(),
          primaryKey: 1
        }
      };
      reg.showNotification('Hello world!', options);
    });
  }
}

给通知添加事件

function displayNotification() {
  if (Notification.permission == 'granted') {
    navigator.serviceWorker.getRegistration().then(function(reg) {
      var options = {
        body: 'Here is a notification body!',
        icon: 'images/example.png',
        vibrate: [100, 50, 100],
        data: {
          dateOfArrival: Date.now(),
          primaryKey: 1
        },
        actions: [//事件按钮列表,可以监听这些按钮的点击事件
          {action: 'explore', title: 'Explore this new world',
            icon: 'images/checkmark.png'},
          {action: 'close', title: 'Close notification',
            icon: 'images/xmark.png'},
        ]
      };
      reg.showNotification('Hello world!', options);
    });
  }
}

监听事件
监听事件在serviceworker.js中

//监听关闭通知事件,比如安卓上面滑动通知关闭。
self.addEventListener('notificationclose', function(e) {
  var notification = e.notification;
  var primaryKey = notification.data.primaryKey;

  console.log('Closed notification: ' + primaryKey);
});

//监听通知的点击事件
self.addEventListener('notificationclick', function(e) {
  var notification = e.notification;
  var primaryKey = notification.data.primaryKey;
  var action = e.action;

  if (action === 'close') {
    notification.close();
  } else {
    clients.openWindow('http://www.example.com');
    notification.close();
  }
});
推送API

通知和推送是不同的,但是他们是互补的。推送是服务器将消息推送给service worker,通知是service worker将消息展现给用户。

网络推送涉及客户端管理和服务器管理。 我们主要关注Web推送的客户端方面,因为它涉及推送通知(Push API)。 我们将把服务器端的细节交给三方提供商,比如firebase等。

web推送的工作原理
我们来看看网页推送的工作原理。

每个浏览器通过自己的系统管理推送通知,称为“推送服务”。 当用户向您的网站授予推送权限时,您可以将该应用程序订阅到浏览器的推送服务。 这将创建一个特殊的订阅对象,其中包含推送服务的“端点URL”(每个浏览器都有所不同)和公钥。 您将推送消息发送到此URL,使用公钥加密,推送服务将其发送到正确的客户端。
如下所示:

{"endpoint":"https://fcm.googleapis.com/fcm/send/dpH5lCsTSSM:APA91bHqjZxM0VImWWqDRN7U0a3AycjUf4O-byuxb_wJsKRaKvV_iKw56s16ekq6FUqoCF7k2nICUpd8fHPxVTgqLunFeVeB9lLCQZyohyAztTH8ZQL9WCxKpA6dvTG_TUIhQUFq_n",
"keys": {
    "p256dh":"BLQELIDm-6b9Bl07YrEuXJ4BL_YBVQ0dvt9NQGGJxIQidJWHPNa9YrouvcQ9d7_MqzvGS9Alz60SZNCG3qfpk=",
    "auth":"4vQK-SvRAN5eo-8ASlrwA=="
    }
}

推送服务如何知道哪个客户端发送消息?端点URL包含一个唯一的标识符。此标识符用于将发送的消息路由到正确的设备,并在浏览器处理时识别哪个service worker处理请求。

标识符是不透明的。作为开发人员,您无法从中确定任何个人数据。此外,它不稳定,所以它不能用来跟踪用户。

由于推送通知与service worker配对,因此使用推送通知的应用程序必须使用HTTPS。这确保了您的服务器和推送服务之间的通信通道是安全的,并且从推送服务到用户也是安全的。

但是,HTTPS不能确保推送服务本身是安全的。我们必须确保从您的服务器发送到客户端的数据不被任何第三方篡改或直接检测。您必须在你的服务器加密消息体。

以下总结了发送和接收推送消息并显示推送通知的过程:

客户端:

订阅推送服务
将订阅对象发送到服务器

服务器端:

生成我们想要发送给用户的数据
用用户公钥加密数据
将加密数据的载体发送到端点URL。

该消息被路由到用户的设备。 这唤醒了浏览器,该浏览器找到正确的service worker并调用“推送”事件。

回到客户端:

接收“推送”事件中的消息数据(如果有)
在推送事件中执行一些自定义逻辑
显示通知

处理推送事件
service worker监听push事件,接收到消息通过通知显示给用户。

serviceworker.js

self.addEventListener('push', function(e) {
  var options = {
    body: 'This notification was generated from a push!',
    icon: 'images/example.png',
    vibrate: [100, 50, 100],
    data: {
      dateOfArrival: Date.now(),
      primaryKey: '2'
    },
    actions: [
      {action: 'explore', title: 'Explore this new world',
        icon: 'images/checkmark.png'},
      {action: 'close', title: 'Close',
        icon: 'images/xmark.png'},
    ]
  };
  e.waitUntil(
    self.registration.showNotification('Hello world!', options)
  );
});

订阅推送通知
在我们发送推送消息之前,我们必须先订阅推送服务。

if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('sw.js').then(function(reg) {
    console.log('Service Worker Registered!', reg);
    //获取订阅信息
    reg.pushManager.getSubscription().then(function(sub) {
      if (sub === null) {
        //未订阅推送服务,更新页面询问用户是否注册推送
      } else {
        // We have a subscription, update the database
        console.log('Subscription object: ', sub);
      }
    });
  })
   .catch(function(err) {
    console.log('Service Worker registration failed: ', err);
  });
}

如果没有订阅对象,我们可以更新我们的用户界面,询问用户是否希望收到通知。
假设用户启用了通知。 现在我们可以订阅推送服务

function subscribeUser() {
  if ('serviceWorker' in navigator) {
    navigator.serviceWorker.ready.then(function(reg) {

      reg.pushManager.subscribe({
        userVisibleOnly: true//将一个名为userVisibleOnly的标志传递给subscribe方法。 通过将其设置为true,浏览器可以确保每个传入消息都具有匹配的(可见的)通知。
      }).then(function(sub) {
        console.log('Endpoint URL: ', sub.endpoint);
      }).catch(function(e) {
        if (Notification.permission === 'denied') {
          console.warn('Permission for notifications was denied');
        } else {
          console.error('Unable to subscribe to push', e);
        }
      });
    })
  }
}

Web推送协议
Web Push协议是发送去往浏览器的推送消息的正式标准。 它描述了如何创建推送消息的结构和流程,对其进行加密并将其发送到Push消息传递平台。 该协议抽象了用户拥有的消息传递平台和浏览器的细节。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值