建议先把参考文章简单看看
参考文章:
https://golb.hplar.ch/2019/08/webpush-java.html
https://developer.mozilla.org/zh-CN/docs/Web/API/Push_API
https://blog.mozilla.org/services/2016/08/23/sending-vapid-identified-webpush-notifications-via-mozillas-push-service/
Push API 给与了 Web 应用程序接收从服务器发出的推送消息的能力,无论 Web 应用程序是否在用户设备前台,甚至刚加载完成。这样,开发人员就可以向用户投放异步通知和更新,从而让用户能更及时地获取新内容。(MDN原文)
参考文章内容较多,但建议先看看
简单来说,web push是一个规范,各个浏览器提供商(现在大概就Google和Mozilla了)为自己的浏览器部署具体的推送服务器。
用户在浏览器发起web push注册时,浏览器会向各自厂商的推送服务器注册自己,如果成功的话,就可以获取到一个“注册信息”,此时后端服务就可以通过这个注册信息向订阅者推送消息
浏览器也会在后台挂起一个处理程序接收通知,消息推送过来时,这个处理程序可以做出一些动作,比如弹出一个消息提示。
国内较少使用这个功能,可能主要问题就是Chromium引擎注册此服务,会返回一个google的接收网址,这个地址是被墙掉的,Firefox浏览器有一个自己的地址(但我没有对FireFox测试过需不需要梯子)。且国内移动互联网生态聚焦于App,App上有另一套推送实现方式。
本文不会记录较详细的代码,主要记录怎么碰壁的
初步对接
最开始对接web push时,我在Github上找到一个开源项目尝试对接,项目的案例里有使用gcm-api-key,实际上完全不用,只是进行推送的话是完全免费的,不需要你去Google进行任何注册。
这个项目的案例是没有使用VAPID 加密的,如果业务需求需要使用的话,记得查看这里把VAPID密钥挂载上
注意国内服务器的后端,推送时需要通过代理,此框架将发送Http请求封装了,需要翻源码将其拆出来
碰壁1
最开始前端在注册时,并没有使用VAPID密钥要求的ECDSA算法生成的公钥,但是使用这个错误算法的公钥竟然是可以成功订阅的,浏览器到推送服务器都不会返回任何错误(至少Google是这样)。推送服务器会照常返回一个订阅消息给你,但这个订阅根本用不了。
但是Java这边,会检查这组密钥是否是ECDSA算法生成的,可能是因为后端这边拥有公私钥,可以验证出来,但推送服务器只持有公钥,是无法验证的。
碰壁2
切换使用ECDSA生成的公私钥向推送服务订阅,但这次还是无法推送出去,而且重复生成几个密钥重复注册都一样,Google都会统一返回验证失败,拼尽全力无法战胜。
之后切换了一台电脑尝试又可以了,发现如果直接调用PushManager.subscribe()进行订阅,实际上是老订阅,不会把老的密钥覆盖掉!需要前端在进行新订阅前手动调用unsubscribe方法将旧订阅停止,然后重新订阅,才会使用新密钥
碰壁3
进行订阅时,需要加载一个js文件,这个文件里需要实现订阅消息的接收处理代码,但是浏览器在重复订阅时,可能会直接使用老的js文件,不会向服务器请求新文件,此时可能需要重启浏览器以消除缓存