防止服务工作者自动停止

Lew*_*wis 15 javascript service-worker

服务工作者似乎在某个时候自动停止.此行为无意中关闭在activate上建立的WebSocket连接.

什么时候停止?如何以编程方式禁用此意外操作以使Service Worker保持运行?

Jef*_*ick 22

你所看到的是预期的行为,它不太可能改变.

服务人员故意维持很短的寿命.他们是"天生"响应特定事件(install,activate,message,fetch,push,等),执行任务,然后在"死"之后不久.生命周期通常足够长,以至于在工人死亡之前可能会处理多个事件(即install可能后面activate跟着a fetch),但最终会死亡.这就是为什么不依赖脚本中的任何全局状态,以及在服务工作者启动时通过IndexedDB或Cache Storage API引导您需要的任何状态信息非常重要的原因.

无论何时访问某些网页,服务工作者都是有效的后台进程.如果允许这些后台进程无限期运行,则会增加对设备/计算机的电池和性能产生负面影响的风险.为了降低这种风险,您的浏览器只会在知道必要时运行这些流程,即响应事件.

用例WebSockets是让客户端从服务器侦听一些数据.对于该用例,服务工作者友好的替代方法WebSockets是使用Push Messaging API并让服务工作者响应push事件.请注意,在当前的Chrome实施中,您必须在处理push事件时显示用户可见的通知.目前push不支持"静默" 用例.

如果不是从服务器监听数据,而是WebSockets用作从客户端向服务器发送数据的方式,不幸的是,没有很好的服务工作者友好的方式.在将来的某个时候,可能有一种方法可以通过定期/基于时间的事件来注册您的服务工作者,此时您可以使用该事件fetch()将数据发送到服务器,但目前在任何浏览器中都不支持.

PS:当你的DevTools界面打开时,Chrome(通常)不会杀死服务工作者,但这只是为了简化调试,而不是你应该依赖的实际应用程序的行为.

  • ServiceWorker用于处理需要在页面上下文之外触发的事件.它不适用于后台处理,这是SharedWorker的用途.如果您尝试使用它进行处理,则可能会阻止对性能很糟糕的获取事件.我们希望在*ServiceWorkers中启用SharedWorkers*,因为它们用于不同的事情. (3认同)
  • 差不多 6 年后,“在未来的某个时刻,可能有一种方法可以注册您的 Service Worker,以便通过定期/基于时间的事件唤醒 […]”_ 对于这个显然非常需要的功能,目前还没有任何计划? (3认同)
  • 这对我来说真的是一个非常糟糕的消息。从你的角度来看,ServiceWorker 与 SharedWorker 相比,实际上只是 ** 更长的存在,而是临时的寿命**而不是更长的寿命。恕我直言,它应该至少在所有依赖页面都关闭之前还活着(如 SharedWorker)。我曾经很喜欢 ServiceWorker,但现在我的心因此彻底碎了。 (2认同)
  • 我认为 PWA 在这里打败了本地应用程序,目前阻碍我们的事情是:长时间运行的后台任务,原始 tcp 和 udp 东西我们在网络上永远无法拥有我宁愿拥有一些允许长时间运行的权限 api sw 或查看浏览器通知执行否定的工作人员。长期运行的服务工作者也有良好的意图。一个简单的提示,“example.com 仍在运行后台处理...... `[destroy]` `[keep alive]` `[ ]` 不要再问”会让我高兴 (2认同)
  • @JaffaTheCake ...这意味着我不应该使用服务工作人员与多个页面共享 WebSocket 连接并保持其活动状态。谢谢你的话。 (2认同)

Umu*_*göz 7

理论

杰夫的回答详细解释了理论部分 - 为什么以及如何。

它还包含许多关于为什么您可能不想追求这一点的好观点。

然而,就我而言,缺点是不存在的,因为我的应用程序将在桌面计算机上运行,​​而这些计算机仅为运行我的应用程序而保留。但即使浏览器窗口最小化,我也需要保持软件处于活动状态。因此,如果您正在开发一个将在各种设备上运行的网络应用程序,那么对于上面答案中讨论的内容来说,保持软件处于活动状态可能不是一个好主意。

话虽如此,让我们转向实际的、实用的答案。

我的“实用”解决方案

应该有很多方法可以让软件保持活动状态,因为软件在响应许多不同的事件后仍然保持活动状态。就我而言,我已将一个虚拟文件放入服务器,将其缓存在软件中,并定期从document.

因此步骤是;

  • 例如,在服务器上创建一个虚拟文件ping.txt
  • 将文件缓存到您的软件上
  • 定期从您的 html 请求该文件以保持软件处于活动状态

例子

// in index.html
setInterval(function(){
    fetch('/ping.txt')
}, 20000)
Run Code Online (Sandbox Code Playgroud)

该请求实际上不会到达服务器,因为它将被缓存在软件上。尽管如此,这将使软件保持活力,因为它将响应fetch请求引发的事件。

PS:我发现 20 秒是保持 SW 存活的良好间隔,但它可能会改变你,你应该尝试一下看看。