基本概念

(1)webapp

网络应用,是指使用web技术实现的应用程序,在web浏览器或其它web运行环境的上下文中执行。

(2)application server

网络应用的服务器,是指webapp的服务器端。

(3)push message

推送消息,是指application server发送给webapp的消息。application server在推送消息给推送服务(例如,GCM)时,会带上push subscription,推送服务会找到与push subscription相关联的active worker ,然后把消息推送给它,并触发它的onpush。

(4)push subscription

推送订阅,是代表webapp在用户代理(例如,浏览器)和推送服务(例如,GCM)之间建立的消息传递上下文。每个push subscription都与一个service worker registration相关联,而一个service worker registration最多只有一个push subscription。每个push subscription都有一个push endpoint和一个公钥,公钥是用于给application server加密要推送的消息数据。

(5)push endpoint

push endpoint,在ServiceWorker向push service注册时,由push service生成。在Chrome 45版本之前,push endpoint是指推送服务的地址,例如,GCM服务器的地址。在Chrome 45及之后版本,push endpoint = push server address + subscriptionId,其中subscriptionId可以唯一标识push subscription。在浏览器客户端,通过subscriptionId可以找到相应的app_id和sender_id。app_id包含作用域和workerId,例如,push#http://example.com/test/#1。

(6)sender_id

sender_id,是创建Google API项目时生成的项目ID。ServiceWorker通过浏览器向GCM注册订阅消息时,需要上传sender_id,才能订阅成功。GCM会使用sender_id,通过Instance ID API到Instance ID Service去注册生成Instance ID,此步骤最终生成的注册信息,也就是前面提到的 subscriptionId。注:Chrome52之前版本对应的GCM/FCM还不支持标准的Web Push Protocol,所以才需要通过gcm_sender_id去找到相应的浏览器客户端,Chrome52版本及其对应的GCM/FCM已支持标准的Web Push Protocol,不再需要sender_id了,即支持标准的Web Push Protocol的push服务器都是不需要sender_id的。

(7)Subscription Refreshes

浏览器或推送服务,可以在任何时间更新push subscription。更新成功后,必须触发与push subscription相关联的service worker registration的pushsubscriptionchange事件,如果更新失败,浏览器应定期触发更新,直至成功。

(8)Subscription Deactivation

push subscription停止使用时,浏览器和推送服务必须删除已保存的副本,相关消息不再推送。service worker registration在注销或清除注册信息时,相关联的push subscription会被停用。

(9)Push service

推送服务,是指一个推送服务系统,允许application server通过它推送消息给webapp。

Push流程

9dd4034cd21c3b4a4e8590e91440a56aa09e0b09

(1)页面向浏览器注册一个ServiceWorker,浏览器生成对应的ServiceWorkerRegistration对象。

(2)页面通过ServiceWorker的PushManager.subscribe方法向push service(GCM)订阅消息,GCM 返回push subscription (endpoint+subscriptionId)给浏览器,浏览器找到对应的ServiceWorker,并把push subscription传递给ServiceWorker。

(3)页面通过PushManager.getSubscription获取到push subscription,并将它发送给页面服务器。注,可以使用ajax请求发送数据给页面服务器。

(4)页面服务器需要推送消息时,将push message和push subscription发送给push service(例如,GCM)。GCM根据push subscription找到对应的浏览器客户端并把消息推送给它,浏览器通过app_id找到相应的ServiceWorker,激活和把消息传递给它并触发它的onpush。

(5)页面JS根据实际需要去处理onpush事件,比如,弹出消息通知,存储数据到本地,提前到服务器去fetch资源,等等。

(6)页面在不再需要订阅消息时,可以发送ajax请求通知页面服务器去清除push subscription。然后使用PushSubscription.unsubscribe向push service去取消订阅。

页面实现消息推送的详细流程,可以参考官方文档 Your First Web Push Notification 和 Push Notifications on the Open Web。

基本流程的示例代码:

// https://example.com/serviceworker.js
this.onpush = function(event) {
console.log(event.data);
// From here we can write the data to IndexedDB, send it to any open
// windows, display a notification, etc.
}
// https://example.com/webapp.js
navigator.serviceWorker.register('serviceworker.js').then(
function(serviceWorkerRegistration) {
serviceWorkerRegistration.pushManager.subscribe().then(
function(pushSubscription) {
console.log(pushSubscription.endpoint);
console.log(pushSubscription.getKey('p256dh'));
console.log(pushSubscription.getKey('auth'));
// The push subscription details needed by the application
// server are now available, and can be sent to it using,
// for example, an XMLHttpRequest.
}, function(error) {
// During development it often helps to log errors to the
// console. In a production environment it might make sense to
// also report information about errors back to the
// application server.
console.log(error);
}
);
});

Push服务

(1)GCM/FCM

a0e09dbd36960b2abe4cebf42dfb627e256be289

注1:页面服务器(app server)使用HTTP/XMPP协议发送消息给Google GCM Connection Servers,GCM Connection Server 推送消息给相应的浏览器客户端。

注2:页面服务器(app server)发送消息的格式如下,

curl--header"Authorization: key=<YOUR_API_KEY>"--header"Content-Type: application/json"https://android.googleapis.com/gcm/send -d"{\"registration_ids\":[\"<YOUR_REGISTRATION_ID>\"]}"

其中,API_KEY 是创建Google API项目时生成的Server Key,GCM可通过它找到对应的sender_id。YOUR_REGISTRATION_ID 是订阅消息时生成的subscriptionId。

注3:Google Chrome是第一个支持Push API的浏览器,最先支持的版本为Chrome 42,这个时候Web Push Protocol还未完稿,所以其push service使用的GCM/FCM服务器并不支持标准Web Push Protocol。Chrome 52版本实现了对标准Web Push Protocol的支持,此时,GCM/FCM也已支持标准Web Push Protocol。

(2)Mozilla Push Service

Mozilla推送服务使用autopush作为它的push服务器。autopush是支持标准Web Push Protocol,它使用websockets与FireFox浏览器进行交互。

Mozilla推送服务的架构如下,

88646f58cce6f45802f9a2f34c8d2a571453b4a8

(3)第三方Push服务

Push API标准是允许替换endpoint的,即任何实现了Web Push Protocol的服务器都可作为endpoint,并且对使用者是透明的。

那么需要做哪些工作来实现我们浏览器自己的push服务呢?

我们先看看Web Push Protocol定义了那些内容:

    +-------+           +--------------+       +-------------+|  UA   |           | Push Service |       | Application |+-------+           +--------------+       |   Server    ||                      |               +-------------+|      Subscribe       |                      ||--------------------->|                      ||       Monitor        |                      ||<====================>|                      ||                      |                      ||          Distribute Push Resource           ||-------------------------------------------->||                      |                      |:                      :                      :|                      |     Push Message     ||    Push Message      |<---------------------||<---------------------|                      ||                      |                      |Figure 1: WebPush Architecture
  1. 浏览器客户端连接push service
    需要使用https。
  2. 浏览器客户端订阅push message
    浏览器需要发送POST请求,到push service去订阅消息。比如,
        POST /subscribe HTTP/1.1
        Host: push.example.net
    订阅成功后push service的响应如下,
        HTTP/1.1 201 Created
        Date: Thu, 11 Dec 2014 23:56:52 GMT
        Link: </push/JzLQ3raZJfFBR0aqvOMsLrt54w4rJUsV>;
                    rel="urn:ietf:params:push"
        Link: </subscription-set/4UXwi2Rd7jGS7gp5cuutF8ZldnEuvbOy>;
                    rel="urn:ietf:params:push:set"
        Location: https://push.example.net/subscription/LBhhw0OohO-Wl4Oi971UG
    这个步骤中,push service需要能够根据不同情况返回不同的响应码,能够识别出同一客户端的请求。
  3. 页面服务器发送推送消息
    application server发送POST请求给push service,请求它将消息推送给浏览器客户端。请求如下,
        POST /push/JzLQ3raZJfFBR0aqvOMsLrt54w4rJUsV HTTP/1.1
        Host: push.example.net
        TTL: 15
        Content-Type: text/plain;charset=utf8
        Content-Length: 36

        iChYuI3jMzt3ir20P8r_jgRR-dSuN182x7iB

    push service的响应如下,
        HTTP/1.1 201 Created
        Date: Thu, 11 Dec 2014 23:56:55 GMT
        Location: https://push.example.net/message/qDIYHNcfAIPP_5ITvURr-d6BGt
    这个步骤中,push service需要能够根据不同情况返回不同的响应码,能够根据TTL保存推送消息一段时间并且含有Topic
    头部的新消息能替换旧消息,能够根据Urgency头部决定推送的优先级。
  4. 浏览器客户端接收订阅的推送消息
    浏览器客户端发GET请求请求接收推送消息,请求信息如下,
        HEADERS [stream 7] +END_STREAM +END_HEADERS
        :method = GET
        :path = /subscription/LBhhw0OohO-Wl4Oi971UG
        :authority = push.example.net
    push service允许保持请求,在application server发送推送消息之后,它将消息通过HTTP/2 server push将消息推送给浏览器客户端,响应信息如下,
        PUSH_PROMISE [stream 7; promised stream 4] +END_HEADERS
        :method = GET
        :path = /message/qDIYHNcfAIPP_5ITvURr-d6BGt
        :authority = push.example.net
        HEADERS [stream 4] +END_HEADERS
        :status = 200
        date = Thu, 11 Dec 2014 23:56:56 GMT
        last-modified = Thu, 11 Dec 2014 23:56:55 GMT
        cache-control = private
        link = </push/JzLQ3raZJfFBR0aqvOMsLrt54w4rJUsV>;
                     rel="urn:ietf:params:push"
        content-type = text/plain;charset=utf8
        content-length = 36
        DATA [stream 4] +END_STREAM
        iChYuI3jMzt3ir20P8r_jgRR-dSuN182x7iB
        HEADERS [stream 7] +END_STREAM +END_HEADERS
        :status = 200
    浏览器客户端接收到消息后,必须回应一个HTTP DELETE给push service,
        DELETE /message/qDIYHNcfAIPP_5ITvURr-d6BGt HTTP/1.1
        Host: push.example.net
    push service在收到浏览器客户端的回应后,必须返回一个204的响应给application server。如果没有收到回应,则会认为消息还未派发到浏览器客户端,
    那么push service应该继续重试,直至消息过期。
  5. 安全隐私方面的考虑
    push服务需要考虑安全相关的一些问题,比如推送的消息需要进行加密,用户设备信息不应包含在消息推送中,过多异常请求时能够拒绝服务,
    服务器日志不应暴露用户信息,等等。

从上面可以看看,push service至少需要具备的一些能力,比如,支持https,支持http/2 server push,支持POST,GET,DELETE请求,能够根据请求生成订阅信息,能够根据请求头部控制响应的优先级,能够存储消息一段时间。即服务器端有一定的实现成本。

Chrome 52已支持标准Web Push Protocol,第三方浏览器可参考其实现,即浏览器端的实现成本会变低。

浏览器支持

在国外,Google Chrome,Firefox,以及一些厂商的系统浏览器,比如三星,都已支持Push API。预计后面会越来越多的浏览器厂商支持。

在国内,还未有浏览器厂商支持Push API,估计这种情况会持续很长一段时间,门槛在于push service的缺失,风险在于内容监管。

从上面我们可以看到,Push API提供了一种页面服务器与页面交互的方法,是web page能成长为web app所需的关键能力。同时,我们也可看到,国内是不能使用GCM/FCM作为push service的,因为需要翻墙。如果我们自己搭建push service,服务器的软硬件都需要不小的成本,估计还未有浏览器厂商愿意承担这个成本。这对一些现有的推送服务商倒是一个十分难得的机遇,支持标准的Web Push Protocol,提供给所有浏览器厂商使用,做成国内最有影响力的推送服务,类似Google的GCM/FCM。

如果Web Push一直得不到支持,对于浏览器SDK来说,可以提供一套非标准的API,允许客户端(比如,手淘)推送消息给浏览器的ServiceWorker,push service则由内置浏览器SDK的客户端自行去实现。

参考文档

Push API - W3C

Web Push Protocol - W3C

Your First Web Push Notification

Push Notifications on the Open Web

Web 推送技术

Web Push Interoperability Wins

Mozilla Push Service

Generic Event Delivery Using HTTP Push

PWA系列 - Web Push 技术相关推荐

  1. PWA(Progressive Web App)入门系列:(三)PWA关键技术Manifest

    前言 前面说过,让Web App能够达到Native App外观体验的主要实现技术就是PWA中的manifest技术,本章会详细说明manifest的实现,及各个参数的具体含义,还将了解如何定义Web ...

  2. PWA(Progressive Web App)入门系列:Push

    前言 很多时候,原生应用会通过一些消息推送来唤起用户的关注,增加驻留率.网页该怎么做呢?有没有类似原生应用的推送机制?推送功能又能玩出什么花样呢? Push API Push API 给与了 Web ...

  3. PWA(Progressive Web App)入门系列:(四)Promise

    前言 这一章说一下ES6的Promise对象.为什么要在PWA系列的文章中讲Promise呢?因为PWA中的许多技术API中都是以Promise返回的方式返回的,为了对后续章节中PWA技术API更好的 ...

  4. NetScaler的Web 2.0 Push技术

    一.前言 通常情况下,异步通知通过使用HTTP和服务器推送技术,如轮训,长轮询和HTTP流,这使得服务器能够将通知推送到浏览器.这些技术需要服务器保持大量的TCP/IP连接,由于其每次连接的时间较短, ...

  5. 【PWA】web推送技术

    伴随着今年 Google I/O 大会的召开,一个很火的概念–Progressive Web Apps 诞生了.这代表着我们 web 端有了和原生 APP 媲美的能力.但是,有一个很重要的痛点,web ...

  6. PWA(Progressive web apps):Web技术实现类似原生应用 - 入门

    PWA(Progressive web apps):Web技术实现类似原生应用 - 入门简介 前言 在(使用Google浏览器)访问一些网站时,有时右上角会弹出"安装应用"的按钮. ...

  7. 从 SPA 到 PWA:Web App的下一站在哪?

    从AJAX(Asynchronous JavaScript + XML,异步JavaScript和XML)开始, 尤其是 AngularJS 推出之后,SPA(Single Page App,单页应用 ...

  8. Web前端技术 Web学习资料 Web学习路线 Web入门宝典(不断更新中)

    (此文档于2019年3月停止再更新,后续更新移步至:https://github.com/liuyuqin1991/polaris) 学习路线 第一章 技术(核心单独列章节) 1.Node Node. ...

  9. PWA (Progressive Web App)

    PWA (Progressive Web App) 1.简介 是一种理念,使用多种技术来增强web app的功能,可以让网站的体验变得更好,能够模拟一些原生的功能,比如:通知推送 Js-to-Nati ...

  10. WijmoJS 使用Web Workers技术,让前端 PDF 导出效率更高效

    概述 Web Workers是一种Web标准技术,允许在后台线程中执行脚本处理. WijmoJS 的2018v3版本引入了Web Workers技术,以便在生成PDF时提高应用程序的运行速度. 一般来 ...

最新文章

  1. Debian 10发布:基于Linux 4.19内核,包含5.9万软件包
  2. java同步机制简单介绍
  3. python获取原图GPS位置信息,轻松得到你的活动轨迹
  4. layui之在table的编辑的按钮的思考
  5. jdk、jre及jvm的关系
  6. Java千百问_07JVM架构(001)_java内存模型是什么样的
  7. 点喷丸打标机行业调研报告 - 市场现状分析与发展前景预测(2021-2027年)
  8. django获取客户ip
  9. 微信小程序双层图片swiper滑动(底部图片模糊处理)实现
  10. QCC3020呼吸灯设计
  11. SQL中drop,delete和truncate的异同
  12. 透明网桥自学习转发帧解题记录
  13. 通过U盘安装windows简易教程
  14. 攻防世界 Web高手进阶区 mfw
  15. SAP SD初阶之VL10A为销售订单创建外向交货单
  16. 基于QT的C++的坦克大战游戏
  17. kernel panic - not syncing : fatal exception
  18. 关系型数据库到文档型数据库的跨越
  19. 2021年G1工业锅炉司炉考试内容及G1工业锅炉司炉考试技巧
  20. 《灵飞经5·龙生九子》第二十三章 力压须眉(上)

热门文章

  1. 四元式的翻译以及寄存器分配
  2. 详解Boost电路的基本原理
  3. 数格子算面积的方法_数方格在平面图形面积公式推导教学中的妙用
  4. 草食と肉食作者小さな塵
  5. 三个月追求金牛全过程(图
  6. vscode修改背景
  7. matlab需要什么运行库,运行库是什么?常用软件运行库都有哪些?
  8. vue前端项目富文本应用
  9. JavaScript 效果 - so cool
  10. 隐藏header html,html5 header标签 css3布局教程