PWA系列 - Web Push 技术
基本概念
(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流程
(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。
基本流程的示例代码:
Push服务
(1)GCM/FCM
注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推送服务的架构如下,
(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
- 浏览器客户端连接push service
需要使用https。 - 浏览器客户端订阅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需要能够根据不同情况返回不同的响应码,能够识别出同一客户端的请求。 - 页面服务器发送推送消息
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头部决定推送的优先级。 - 浏览器客户端接收订阅的推送消息
浏览器客户端发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应该继续重试,直至消息过期。 - 安全隐私方面的考虑
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 技术相关推荐
- PWA(Progressive Web App)入门系列:(三)PWA关键技术Manifest
前言 前面说过,让Web App能够达到Native App外观体验的主要实现技术就是PWA中的manifest技术,本章会详细说明manifest的实现,及各个参数的具体含义,还将了解如何定义Web ...
- PWA(Progressive Web App)入门系列:Push
前言 很多时候,原生应用会通过一些消息推送来唤起用户的关注,增加驻留率.网页该怎么做呢?有没有类似原生应用的推送机制?推送功能又能玩出什么花样呢? Push API Push API 给与了 Web ...
- PWA(Progressive Web App)入门系列:(四)Promise
前言 这一章说一下ES6的Promise对象.为什么要在PWA系列的文章中讲Promise呢?因为PWA中的许多技术API中都是以Promise返回的方式返回的,为了对后续章节中PWA技术API更好的 ...
- NetScaler的Web 2.0 Push技术
一.前言 通常情况下,异步通知通过使用HTTP和服务器推送技术,如轮训,长轮询和HTTP流,这使得服务器能够将通知推送到浏览器.这些技术需要服务器保持大量的TCP/IP连接,由于其每次连接的时间较短, ...
- 【PWA】web推送技术
伴随着今年 Google I/O 大会的召开,一个很火的概念–Progressive Web Apps 诞生了.这代表着我们 web 端有了和原生 APP 媲美的能力.但是,有一个很重要的痛点,web ...
- PWA(Progressive web apps):Web技术实现类似原生应用 - 入门
PWA(Progressive web apps):Web技术实现类似原生应用 - 入门简介 前言 在(使用Google浏览器)访问一些网站时,有时右上角会弹出"安装应用"的按钮. ...
- 从 SPA 到 PWA:Web App的下一站在哪?
从AJAX(Asynchronous JavaScript + XML,异步JavaScript和XML)开始, 尤其是 AngularJS 推出之后,SPA(Single Page App,单页应用 ...
- Web前端技术 Web学习资料 Web学习路线 Web入门宝典(不断更新中)
(此文档于2019年3月停止再更新,后续更新移步至:https://github.com/liuyuqin1991/polaris) 学习路线 第一章 技术(核心单独列章节) 1.Node Node. ...
- PWA (Progressive Web App)
PWA (Progressive Web App) 1.简介 是一种理念,使用多种技术来增强web app的功能,可以让网站的体验变得更好,能够模拟一些原生的功能,比如:通知推送 Js-to-Nati ...
- WijmoJS 使用Web Workers技术,让前端 PDF 导出效率更高效
概述 Web Workers是一种Web标准技术,允许在后台线程中执行脚本处理. WijmoJS 的2018v3版本引入了Web Workers技术,以便在生成PDF时提高应用程序的运行速度. 一般来 ...
最新文章
- Debian 10发布:基于Linux 4.19内核,包含5.9万软件包
- java同步机制简单介绍
- python获取原图GPS位置信息,轻松得到你的活动轨迹
- layui之在table的编辑的按钮的思考
- jdk、jre及jvm的关系
- Java千百问_07JVM架构(001)_java内存模型是什么样的
- 点喷丸打标机行业调研报告 - 市场现状分析与发展前景预测(2021-2027年)
- django获取客户ip
- 微信小程序双层图片swiper滑动(底部图片模糊处理)实现
- QCC3020呼吸灯设计
- SQL中drop,delete和truncate的异同
- 透明网桥自学习转发帧解题记录
- 通过U盘安装windows简易教程
- 攻防世界 Web高手进阶区 mfw
- SAP SD初阶之VL10A为销售订单创建外向交货单
- 基于QT的C++的坦克大战游戏
- kernel panic - not syncing : fatal exception
- 关系型数据库到文档型数据库的跨越
- 2021年G1工业锅炉司炉考试内容及G1工业锅炉司炉考试技巧
- 《灵飞经5·龙生九子》第二十三章 力压须眉(上)