【问题标题】:Do Shared Web Workers persist across a single page reload, link navigationShared Web Workers 是否在单个页面重新加载、链接导航中持续存在
【发布时间】:2012-03-09 08:32:35
【问题描述】:

Shared Web Workers 旨在允许来自同一站点(来源)的多个页面共享一个 Web Worker。

但是,从规范(或有关 Shared Worker 的其他教程和信息)中,我不清楚如果站点中只有一个窗口/选项卡并且导航到同一站点上的另一个页面,Shared Worker 是否会持续存在.

这对于来自 Shared Worker 的 WebSocket 连接最有用,该连接在站点导航时保持连接。例如,想象一个股票行情或聊天区域,即使在浏览网站时也会持续存在(无需重新连接 WebSocket)。

【问题讨论】:

标签: javascript multithreading html websocket web-worker


【解决方案1】:

我已经进行了一些测试以在实践中找出答案。

Firefox 尚不支持从 Web Workers 创建 WebSocket 连接:https://bugzilla.mozilla.org/show_bug.cgi?id=504553 因此,在解决该错误之前,Firefox 不相关。

IE 10 没有 support for Shared Web Workers 所以它也不相关。这样就离开了 Chrome。

这是一个测试共享网络工作者的示例。

首先是 HTML:

<!DOCTYPE html>
<html>
<body>
    <a href="shared.html">reload page</a>
    <script>
        var worker = new SharedWorker("shared.js");
        worker.port.addEventListener("message", function(e) {
            console.log("Got message: " + e.data);
        }, false);
        worker.port.start();
        worker.port.postMessage("start");
    </script>
</body>
</html>

然后在shared.js中实现shared worker本身:

var connections = 0;

self.addEventListener("connect", function(e) {
    var port = e.ports[0];
    connections ++;
    port.addEventListener("message", function(e) {
        if (e.data === "start") {
            var ws = new WebSocket("ws://localhost:6080");
            port.postMessage("started connection: " + connections);
        }
    }, false);
    port.start();
}, false);

Chrome 20 中的测试结果(答案):

当在两个单独的选项卡中同时加载页面时,每次重新加载其中一个页面或单击自引用链接时,连接数都会增加。

如果仅加载页面的单个实例,则在重新加载页面或单击链接时连接计数永远不会改变。

因此,在 Chrome 20 中:Shared Web Workers 不会在页面重新加载和链接导航点击之间持续存在

【讨论】:

  • 如果我重新加载页面或打开一个新页面 - SharedWorker 会重新创建吗?我写 console.log(new Date().getTime());页面重新加载后,时间总是在控制台中显示不同。所以总是在页面重新加载后创建一个新的 WebSocket 实例,对吗?
【解决方案2】:

看来这和the question 'What happens to an HTML5 web worker thread when the tab is closed while it's running?'基本是一样的问题。我认为规范的关键部分是this statement:

用户代理可以调用​​“kill a worker”处理模型 任何时候的工人,例如响应用户请求,响应 CPU 配额管理,或当工作人员停止活动时需要 工人,如果工人在其关闭标志之后继续执行 设置为 true。

active needed worker”定义如下:

如果 Document 工作人员 Documents 中的对象完全处于活动状态。

因此,据我了解,如果所有引用工作人员的窗口都已关闭,则规范要求浏览器终止工作人员,但不是立即终止。因此,即使它看起来偶尔工作,也依赖于它持久化将是不可靠的。

在您的示例中,我的方法是通过 Ajax 加载整个网站 - 如果您的用户禁用了 JS,您将无法运行 Web Worker,然后使用 History API 创建用户页面地址对应实际页面(保持搜索引擎和非JS兼容)。

【讨论】:

  • 我的问题是在 同一站点 上从一个页面到另一个页面的转换(链接点击)(或重新加载同一站点)是否会将工作人员移动到非active 需要的状态,以及这是否会导致它被杀死。换句话说,它是从活动状态变为活动状态,还是在下一页加载之前先转换为非活动状态(如果是这样,那么这段时间是否足够长)?这实际上是一个关于浏览器实际做什么以及意图是什么的问题。规范措辞本身是模棱两可的,这就是我要问的原因。
  • @kanaka 是的,卸载页面会将其移动到应该被终止的状态(请参阅step 5),但规范并不要求立即终止它。正如我所说,它可能偶尔会起作用,但不要指望它是可靠的。如果你想知道浏览器到底做了什么,试试吧。
【解决方案3】:

我已经通过一种有点迂回的技术取得了成功,当我想转到下一页但要维护 SharedWorker 时,我会打开一个(希望不引人注意的)弹出窗口来创建相同的 worker,等待它变得活跃并向原始端口/窗口发送一条消息,然后导航到新页面,然后在该页面加载时关闭弹出窗口。此策略始终保持至少一个活动连接,因此工作人员永远不会决定关闭。

到目前为止,这种技术似乎相当强大。虽然看到弹出窗口有点烦人,但对于某些用例来说这是一个合理的折衷方案。

【讨论】:

  • 你能给我看看你的例子吗?即使在页面重新加载后,我也总是创建一个新的。
猜你喜欢
  • 2016-10-28
  • 1970-01-01
  • 1970-01-01
  • 2011-09-12
  • 1970-01-01
  • 2018-01-27
  • 2021-11-11
  • 2014-02-11
  • 1970-01-01
相关资源
最近更新 更多