服务工作者似乎在某个时候自动停止。此行为无意中关闭了在激活时建立的WebSocket连接。
何时以及为何停止?如何以编程方式禁用此意外操作以使Service Worker保持运行?
答案 0 :(得分:21)
您所看到的是预期的行为,并且不太可能发生变化。
服务人员故意维持很短的寿命。他们是“天生的”,以响应特定事件(install
,activate
,message
,fetch
,push
等等,执行他们的任务,然后不久就“死”。生命周期通常足够长,可以处理多个事件(即install
后面可能跟activate
后跟fetch
},但最终会死亡。这就是为什么不依赖脚本中的任何全局状态,以及在服务工作者启动时通过IndexedDB或Cache Storage API引导您需要的任何状态信息非常重要的原因。
服务工作者实际上是在您访问某些网页时安装的后台进程。如果允许这些后台进程无限期运行,则会增加对设备/计算机的电池和性能产生负面影响的风险。为了降低这种风险,您的浏览器只会在知道必要时运行这些流程,即响应事件。
WebSockets
的用例是让您的客户端侦听来自服务器的一些数据。对于该用例,使用WebSockets
的服务工作者友好的替代方法是使用Push Messaging API并让服务工作者响应push
事件。请注意,在当前的Chrome实施中,您必须在处理push
事件时显示用户可见的通知。目前不支持“无声”push
用例。
如果不是从服务器监听数据,而是使用WebSockets
作为从客户端向服务器发送数据的方式,遗憾的是没有一种很好的服务工作者友好的方式。在将来的某个时候,可能有一种方法可以通过定期/基于时间的事件来注册您的服务工作者,然后您可以使用fetch()
将数据发送到服务器,但这是当前的在任何浏览器中都不受支持。
PS:当你的DevTools界面打开时,Chrome(通常)不会杀死服务工作者,但这只是为了简化调试,而不是你应该依赖的实际应用程序的行为。
答案 1 :(得分:1)
理论
Jeff's answer explains 理论部分 - 详细说明原因和方式。
它还包含许多关于为什么您可能不想追求这一点的优点。
但是,就我而言,缺点是不存在的,因为我的应用程序将在台式机上运行,而台式机仅为运行我的应用程序而保留。但即使浏览器窗口最小化,我也需要让软件保持活动状态。因此,如果您正在开发可在各种设备上运行的网络应用,那么对于上述答案中讨论的内容,保持软件处于活动状态可能不是一个好主意。
话虽如此,让我们转向实际的、实用的答案。
我的“实用”解决方案
应该有很多方法可以让 SW 保持活跃,因为 SW 在响应许多不同的事件后仍然保持活跃。就我而言,我已将一个虚拟文件放入服务器,将其缓存在 SW 中,并定期从 document
请求该文件。
因此步骤是;
ping.txt
示例
// in index.html
setInterval(function(){
fetch('/ping.txt')
}, 20000)
请求实际上不会到达服务器,因为它会被缓存在软件上。尽管如此,这将使软件保持活动状态,因为它甚至会响应由请求引起的 fetch
。
PS:我发现 20 秒是让软件保持活动状态的良好间隔,但它可能会因您而改变,您应该尝试看看。