kan*_*aka 22 javascript html5 multithreading web-worker websocket
共享Web Workers旨在允许来自同一站点(源)的多个页面共享单个Web Worker.
但是,如果您只有一个窗口/选项卡并且您导航到同一站点上的另一个页面,那么我不清楚规范(或其他有关共享工作者的教程和信息)共享工作者是否会持久存在.
这对于来自共享工作者的WebSocket连接的情况最有用,该连接在网站导航时保持连接.例如,想象一下即使在网站导航时也会持续存在的股票代码或聊天区域(无需重新连接WebSocket).
kan*_*aka 23
我做了一些测试,以便在实践中找到答案.
Firefox还不支持从Web Workers创建WebSocket连接:https://bugzilla.mozilla.org/show_bug.cgi?id = 504553因此,在解决该bug之前,Firefox不相关.
IE 10不支持共享Web工作者,因此它也不相关.这就离开了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>
Run Code Online (Sandbox Code Playgroud)
然后是共享工作者本身的实现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);
Run Code Online (Sandbox Code Playgroud)
Chrome 20中的测试结果(答案):
当页面同时加载到两个单独的选项卡中时,每次重新加载其中一个页面或单击自引用链接时,连接计数都会增加.
如果仅加载页面的单个实例,则在重新加载页面或单击链接时,连接计数永远不会更改.
因此,在Chrome 20中:共享Web工作人员不会在页面重新加载和链接导航点击中保持不变.
我已经成功地采用了一种迂回技术,当我想要转到下一页但维护 SharedWorker 时,我打开一个(希望不引人注目的)弹出窗口来创建相同的工作线程,等待它变为活动状态并发送消息到原始端口/窗口,然后导航到新页面,然后在该页面加载时关闭弹出窗口。这一策略始终保持至少一个活动连接,因此工作线程永远不会决定关闭。
到目前为止,这项技术似乎相当稳健。尽管看到弹出窗口有点烦人,但对于某些用例来说这是一个合理的折衷方案。
看起来这个问题与"运行时关闭选项卡时HTML5 Web工作线程会发生什么?"这个问题基本相同?.我认为规范的关键部分是这个声明:
用户代理可以在任何时间调用工作者的"杀死工作者"处理模型,例如响应于用户请求,响应CPU配额管理,或者如果工作者在工作者继续执行后停止成为活动需要的工作者它的结束标志设置为true.
" 活跃的需要工人 "定义如下:
如果工作者文档中的任何Document对象完全处于活动状态,则称工作者是活动的需要工作者.
因此,据我所知,如果所有引用工作者的窗口都关闭,那么规范要求浏览器终止工作者,但不是立即.因此,即使它偶尔起作用,持久性也将是不可靠的.
在您的示例中,我的方法是通过Ajax加载整个站点 - 如果您的用户无论如何都禁用了JS,您将无法运行Web Workers,然后使用History API使用户的页面地址对应于实际页面(维护搜索引擎和非JS兼容性).