共享Web工作人员是否在单页重新加载,链接导航中持续存在

时间:2012-02-17 23:14:59

标签: javascript multithreading html5 websocket web-worker

Shared Web Workers旨在允许来自同一网站(来源)的多个网页共享一个网络工作者。

但是,如果您只有一个窗口/选项卡并且您导航到同一站点上的另一个页面,那么我不清楚规范(或其他有关共享工作者的教程和信息)共享工作者是否会持久存在

这对于来自共享工作者的WebSocket连接最有用,该连接在网站导航时保持连接状态。例如,设想一个股票代码或聊天区域,即使在网站导航时也会持续存在(无需重新连接WebSocket)。

3 个答案:

答案 0 :(得分:23)

我已经做了一些测试,以便在实践中找到答案。

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

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

以下是测试共享Web工作者的示例。

首先是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中实现共享工作者:

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中:共享网络工作者不会在页面重新加载和链接导航点击中保持

答案 1 :(得分:5)

这似乎与the question 'What happens to an HTML5 web worker thread when the tab is closed while it's running?'基本相同。我认为规范的关键部分是this statement

  

用户代理可以在a上调用“kill a worker”处理模型   工人在任何时候,例如响应用户请求,以响应   CPU配额管理,或者当工作人员不再需要活动时   如果工人即使在关闭标志之后仍继续执行工人   被设置为真。

active needed worker”的定义如下:

  

如果任何文件,工作人员被认为是活跃的需要工人   工人文档中的对象完全有效。

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

在您的示例中,我的方法是通过Ajax加载整个站点 - 如果您的用户无论如何都禁用了JS,那么您将无法运行Web Workers,然后使用History API来创建用户的页面地址对应于实际页面(维护搜索引擎和非JS兼容性)。

答案 2 :(得分:3)

我已经成功使用了一种稍微迂回的技术,当我想要进入下一页但是维护SharedWorker时,我打开了一个(希望不引人注目的)弹出窗口,它创建了同一个工作者,等待它变为活动状态发送消息到原始端口/窗口,然后导航到新页面,然后,当该页面加载时,关闭弹出窗口。此策略始终至少保持一个活动连接,因此工作人员永远不会决定关闭。

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