27

Service Worker 似乎会在某个时候自动停止。此行为无意中关闭了在激活时建立的 WebSocket 连接。

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

4

2 回答 2

45

您所看到的是预期的行为,并且不太可能改变。

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

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

一个用例WebSockets是让您的客户端监听来自服务器的一些数据。对于该用例,服务工作者友好的替代方法WebSockets是使用推送消息 API并让您的服务工作者响应push事件。请注意,在当前的 Chrome 实现中,您必须在处理push事件时显示用户可见的通知。push目前不支持“静默”用例。

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

PS:Chrome(通常)不会在您打开其 DevTools 界面时杀死服务人员,但这只是为了简化调试,而不是您应该依赖于真实应用程序的行为。

于 2015-04-20T14:39:28.353 回答
1

理论

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

它还包括许多关于您可能不想追求这一点的好处。

但是,在我的情况下,缺点是不存在的,因为我的应用程序将在桌面机器上运行,这些机器只保留运行我的应用程序。但是即使浏览器窗口被最小化,我也需要保持 SW 活着。因此,如果您正在开发一个将在各种设备上运行的 Web 应用程序,那么对于上述答案中讨论的事情,保持 SW 活动可能不是一个好主意。

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

我的“实用”解决方案

应该有很多方法可以让 SW 保持活力,因为 SW 在响应许多不同的事件后会保持活力。就我而言,我将一个虚拟文件放到服务器上,将其缓存在 SW 中,并定期从document.

因此,步骤是;

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

例子

// in index.html
setInterval(function(){
    fetch('/ping.txt')
}, 20000)

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

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

于 2021-07-27T21:51:44.297 回答