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

发布于 2025-01-07 07:23:56 字数 337 浏览 0 评论 0 原文

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

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

当来自共享工作线程的 WebSocket 连接在站点导航时保持连接时,这将非常有用。例如,想象一下,即使在浏览网站时,股票行情或聊天区域也会持续存在(无需重新连接 WebSocket)。

Shared Web Workers are designed to allow multiple pages from the same site (origin) to share a single 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.

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

十二 2025-01-14 07:23:56

我做了一些测试,以在实践中找出这个问题的答案。

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

IE 10 不支持共享 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 中共享工作线程本身的实现:

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 中:共享 Web Worker 不会在页面重新加载和链接导航点击时持续存在

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=504553 So Firefox is not relevant until that bug is resolved.

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

Here is an example to test shared web workers.

First the 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:

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):

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.

软糯酥胸 2025-01-14 07:23:56

看来这基本上与 问题“当选项卡在运行时关闭时,HTML5 Web 工作线程会发生什么?”。我认为规范的关键部分是 此声明

用户代理可以调用​​“杀死一个工人”处理模型
工作人员随时,例如响应用户请求、响应
CPU 配额管理,或者当工作人员不再是活跃需求时
如果worker即使在关闭标志后仍继续执行
已设置为 true。

'活跃的需要工作人员< /a>' 定义如下:

如果满足以下任何条件,则称该工人为活跃所需工人
工作人员文档中的对象完全处于活动状态。

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

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

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:

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.

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 API to make the user's page address correspond to the actual page (maintaining search engine and non-JS compatibility).

波浪屿的海角声 2025-01-14 07:23:56

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

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

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.

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文