javascript Shared Web Workers 是否在单个页面重新加载、链接导航中持续存在

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9336774/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 06:19:05  来源:igfitidea点击:

Do Shared Web Workers persist across a single page reload, link navigation

javascriptmultithreadinghtmlwebsocketweb-worker

提问by kanaka

Shared Web Workersare designed to allow multiple pages from the same site (origin) to share a single Web Worker.

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

However, it's not clear to me from the spec (or other tutorials and information on Shared Workers) whether the Shared Worker will persist if you have only one window/tab from the site and you navigate to another page on the same site.

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

This would be most useful in the case of a WebSocket connection from the Shared Worker that stays connected as the site is navigated. For example, imagine a stock ticker or chat area that would persist (without having to reconnect the WebSocket) even while the site is navigated.

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

回答by kanaka

I have done some testing to find out the answer to this in practice.

我做了一些测试,以在实践中找出答案。

Firefox does not yet support creating WebSocket connections from Web Workers: https://bugzilla.mozilla.org/show_bug.cgi?id=504553So Firefox is not relevant until that bug is resolved.

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

IE 10 doesn't have support for Shared Web Workersso it's not relevant either. So that leaves Chrome.

IE 10 不支持 Shared Web Workers,所以它也不相关。这样就剩下 Chrome 了。

Here is an example to test shared web workers.

这是一个测试共享 Web Worker 的示例。

First the HTML:

首先是 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>

Then the implementation of the shared worker itself in shared.js:

然后共享 worker 本身的实现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);

Test results in Chrome 20 (the answer):

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

When the page is loaded simultaneously in two separate tabs, the connection count grows each time one of the pages is reloaded or the self-referential link is clicked.

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

If only a single instance of the page is loaded then the connection count never changes when the page is reloaded or the link is clicked.

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

So, in Chrome 20: Shared Web Workers do not persist across page reloads and link navigation clicks.

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

回答by robertc

It seems like this is basically the same problem as the question 'What happens to an HTML5 web worker thread when the tab is closed while it's running?'. I think the key part of the spec is this statement:

这似乎与问题“HTML5 Web 工作线程在运行时关闭选项卡时会发生什么情况?”基本相同。. 我认为规范的关键部分是这个声明

User agents may invoke the "kill a worker" processing model on a worker at any time, e.g. in response to user requests, in response to CPU quota management, or when a worker stops being an active needed worker if the worker continues executing even after its closing flag was set to true.

用户代理可以在任何时候调用一个 worker 上的“kill a worker”处理模型,例如响应用户请求,响应 CPU 配额管理,或者当一个 worker 不再是一个活跃的需要的 worker 时,如果 worker 继续执行,即使在它的结束标志设置为真。

An 'active needed worker' is defined as follows:

一个“主动需要的工人”定义如下:

A worker is said to be an active needed worker if any of the Document objects in the worker's Documents are fully active.

如果工作人员的文档中的任何文档对象完全处于活动状态,则称工作人员是活动的需要工作人员。

So, as I understand it, if all the windows referencing a worker are closed then the browser is required by the spec to terminate the worker, but not immediately. Depending on it persisting will therefore be unreliable even if it appears to work occasionally.

因此,据我所知,如果所有引用工作人员的窗口都关闭,则规范要求浏览器终止工作人员,但不是立即终止。因此,即使它似乎偶尔工作,坚持下去也是不可靠的。

In your example my approach would be to load the whole site by Ajax - you're not going to be able to run the Web Workers if your users have JS disabled anyhow, then use the History APIto make the user's page address correspond to the actual page (maintaining search engine and non-JS compatibility).

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

回答by Jeremy

I have had success with a somewhat roundabout technique whereby when I want to go to the next page but maintain the SharedWorker, I open up a (hopefully unobtrusive) popup window that creates the same worker, wait for it to become active and send a message to the original port/window, which then navigates to the new page and then, when that page loads, closes the popup. This strategy maintains at least one active connection at all times, so the worker never decides to shut down.

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

This technique seems to be fairly robust so far. Although seeing the popup is somewhat annoying, it's a reasonable compromise for some use cases.

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