请选择 进入手机版 | 继续访问电脑版
Mozilla

火狐社区

登录    注册

用新浪微博连接 QQ互联

破解Mozilla Firefox中Web Push的bug

yingliu Mozilla员工 发表于 2017-6-9 15:53:41 | 显示全部楼层 [复制链接]
1 3028
前言
本文是关于 Mozilla 内 Web 推送服务和 Web Push 使用方法的系列文章之一。作者的用意并非提供一般性的指引,而是对 Web Push 提供最佳使用方法和建议,并设定读者对于 JavaScript、Python 或其他相关技术有一定的了解。

1QNGc6k4faQ.png
Web Push 上的一大挑战是要找出问题点(bug)。Web Push 有大量的「可动部件」、系统和组件,所有的元素都必须彼此合作,才能成功完成信息的推送和接收。虽然这篇文章无法一一说明导致推送通知失败的原因,但会针对常见的问题提供实用的工具和建议。

常见问题

错误回报
最大的问题源自于网站忽略提供的return codes。不久前在另一篇文章中曾建议,可通过订阅服务减少发送失败信息的成本。花点心思留意系统传回的状态代码也是很重要的。

譬如,错误信息的正文(body)可能是这样:
{
‘errno’: 102,
‘message’: ‘Requestdid not validate invalid token’,
‘code’: 404,
‘error’: ‘NotFound’
}

你可在 Autopush 文档中找到错误值的清单(Autopush 是用来执行接收和转寄推送订阅更新的开源服务器的名称)。因为 Autopush 服务器会尽可能提供详细和有用的数据,所以,如果有通知发不出去,Autopush的信息应该会很有帮助。

VAPID 的问题
另一个潜在问题点则与 VAPID 有关。VAPID 是能让提供订阅服务的网站「表明身份」的新兴标准,也就是说,当重大问题发生时,推送服务的服务器运营者便有办法联系到问题通知的来源。假使你看到大量带有 401 状态代码的响应消息,十之八九是因为 VAPID 验证出了差错。

VAPID 还能让网站设定「限制性订阅」。此做法能把订阅锁住,只允许拥有 VAPID 密钥的人发送订阅通知。这其中的原理有点复杂。

但简单来说,VAPID 是以密钥密码签署的数据区块。此密钥有两个部分,其一是用以签署 VAPID 代码(token)、绝对不能分享给他人的私钥;其二则是负责制作限制性订阅、可透露给他人的公钥。一般来说,VAPID 密钥可以维持一段时间不变——约一年左右,但绝不能万年不变。稍后会进一步说明。

当你的应用程序提出推送端点请求时,你可以选择把 VAPID 的公钥当作应用服务器密钥(applicationServerKey)来提供。这会产生一个只有该密钥能开启的新订阅端点。若要成功发送订阅请求,你必须以相应的私钥来签署 VAPID 区块,并在请求中包含公钥(在请求内加入公钥的方式会因 Draft 01 及Draft 02有区别。你或许需要能辅助授权签署的数据库,也不妨先参考推送服务的文档,了解一下其所接受的格式。大多数的推送平台都接受 Draft 02)。

请注意,VAPID 公钥会跟你请求的 URL 绑在一起,也就是说,之后每当你想送数据给该 URL,都必须使用同样的密钥组合。假如你想换 VAPID 密钥,就得先取得新端点后再删除旧的。当然你有权决定如何处理。你的 app 可以从已知的地址取得新的公钥,产生新的 URL 请求后,再把新的注册信息传回给服务器。这会使用到你在 pushsubscriptionchange 事件上会用的大部分的程序代码。

出现 VAPID 401 错误时,你应该确认以下三点:
  • 你是不是用同样的密钥组合来存取限制性订阅的内容?
  • 你是否已正确签署 VAPID 授权密钥?
  • 你的请求是否涵盖了所有必要的VAPID 标头?

数据加密
推送信息的加密方法也有可能造成推送失败。不过,由于推送服务器在接受信息时,根本无从判断信息是否正确加密,也使得这成为最难排错的问题。还有,用户代理程序(User Agent,UA)只会递送它能成功解密的信息。这能避免应用程序因收到大量错误信息而吃掉手机电池太多的电量。

同样的,解决这类问题最有效的办法是使用数据库。不过,数据库也不是万灵丹,在某些状况下,你恐怕还是得自己动手做。这个网页提供了数据加密的步骤,不过,目前只有 Firefox 支持此机制。

请留意,Push Service有部分新规则仍未获得普遍支持。至规则发布之际,大多的推送平台都将接受 ECE Draft 03(aesgcm)编码。虽然已有人提议 UA 应回传其所支持的密码形态,但该提案尚未获得正式采纳。不过,这就是使用尚在发展中的技术会出现的问题。如果你想要掌握最新的规则提案,你可关注Push Service 的工作小组。

可惜的是,因为 PushService 无法解密信息,所以难以侦测到许多的加密错误。幸运的是,我们可以“窥视”客户端,判断其中是否有bug。

为桌面系统排错
你可以运用浏览器控制台(Browser Console)来帮桌面排错。请注意,这个控制台不是开发者工具面板上的 Web 控制台(Web Console)。浏览器控制台能比网页或web控制台呈现更高层级的信息。

这样的好处是,你可以看到你的server worker 的日志,也能看到其他的推送通知。譬如,下面是一个测试页,你或许能看到一些和你的浏览器相似的东西:
2YKhKPgGrqCST.png
(上图:浏览器控制台输出信息的范例)

在窗口下方有四个来自“sw.js” 的信息。前三个是console.info() 信息,分别说明一个新通知已送达、该通知的内容是什么,以及相关的客户端为何。需要特别注意的是第四个信息—— console.error(),内容为「Service worker couldn’tsend message: Error: No valid client to send to」。当service worker 和其 parent 失去关联时,这种状况便可能发生。简单来说,这四个信息传达了一个好消息和一个坏消息:好消息是,推送的通知完好无缺地抵达了,但坏消息是,它无处可去。

另一个实用的资源是在 about:debugging#workers的「service worker debugging」页,里面提供了所有已注册的 service worker 脚本(script),让你取消注册、选择性地发送推送消息、并帮 service worker 脚本排错。你可在 Mozilla Hacks上找到更多有关 about:debugging页的说明

为Android 设备排错
帮 Android 设备的推送功能排错的方法也差不多。就像帮桌面端排错一样,你必须把 dom.push.debug 设为「true」,并把 dom.push.loglevel 设为「debug」。只不过,Android 不像桌面系统有浏览器控制台来让你轻松掌握所有信息。所有的通知都会被记录到 Android 的错误日志里,所以你可以通过adb logcat 等指令来追踪错误的记录。有些开发人员也会使用 grep 来找有“Gecko(Push|Console)”的记录。

下面的画面虽然不太美观,但呈现出来的内容相差不大,其中也包括有助于锁定和解决程序错误的 service workers 的控制台信息。另外,值得一提的是,太长的信息可能会被adb 截短。

adb 记录的例子(原文画面可上下左右滚动,此处只是截图贴上):
302ssSWJ9q1JS.png

从上图来看,可以从中得到更多的信息,包括 GCM 已收到信息并已传给 Gecko。为了节省空间,其中不少日志信息已被移除或缩短,但仍然可以辨别问题究竟是在你的app还是在网络中。

结论
使用 Push 的好处虽多,但千万别忘了,这技术毕竟还很新。有些东西可能会变,有些问题也要小心提防。欢迎与我们分享你碰到的程序错误(bug),并提供建议,帮助我们不断改进。若你有任何问题,也欢迎到 irc.mozilla.org 上提问(#push)。


译自原文

310971373 狐狸精
发表于 2017-6-12 09:41:45 | 显示全部楼层
沙发沙发,调试测试很重要哦!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

发新帖
论坛更多 »
热门活动更多 »
  • [免费报名]量子火狐中国社区见面会 Firefox Quantum Fan Meeting[...

    立即参与
火狐微信
快速回复 返回顶部 返回列表