如何保持页面之间的WebSockets连接?

在我的脚本之一,我有这个代码:

var webSocket = window.WebSocket || window.MozWebSocket; window.ws = new webSocket('ws://64.121.210.140:2585/consoleappsample', 'my-protocol'); 

哪个工作正常。 但是,当用户更改页面时,我必须重新build立连接。 我相信这是我的代码导致的问题,因为如果客户端发送数据到服务器,然后更改页面,数据可能不会收到和竞争条件发生。

我试图把window.ws放在全局范围内,但似乎没有解决这个问题。 有什么办法可以使WebSockets连接在页面之间保持连接,所以连接不需要不断重新build立?

您提到的全局范围始终与JavaScript上下文相关,并且为每个窗口创build一个上下文(并在文档从内存中卸载时销毁)。 因此,您的努力是无用的:如果用户更改页面,则无法保持连接打开。 当然,你可以把你的webapp作为“单页面”应用程序,所有的数据都使用XMLHttpRequest / ajax / WebSocket加载。 所以,离开页面意味着离开/closures应用程序,并且合理地closures套接字。

另一个旧的方法可以把你的页面放在一个框架中,用户只在框架中导航(即使它占用整个窗口的大小)。 这样,你可以在最上面的窗口中创build你的WebSocket,这是永远不会改变的(这也意味着在地址栏中显示的URL将始终是相同的)。

说,我同意@dystroy:你的应用程序应该总是能够处理这种情况 – 用户可能有一些networking问题,失去了连接片刻,即使它不离开页面。

您可以尝试在Shared WebWorker中创buildWebSocket连接,该WebWorker允许来自同一个域的多个页面共享一个执行上下文。 然而,目前还不清楚共享工作者是否持续在一个页面上重新加载或replace: 共享Web工作者持续在单个页面上重新加载,链接导航

而且,共享Web工具目前只有有限的浏览器支持 (webkit和Opera)。

更新

由于一个共享的networking工作者可以为多个页面服务,所以实现比正常的networking工作者稍微复杂一些。

这是一个共享的networking工作者的例子,使用WebSockets,可以共享

首先是HTML:

 <!DOCTYPE html> <html> <body> <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的shared.js

 var ws = null var url = "ws://" + location.hostname + ":6080" self.addEventListener("connect", function(e) { var port = e.ports[0] port.addEventListener("message", function(e) { if (e.data === "start") { if (ws === null) { ws = new WebSocket(url); port.postMessage("started connection to " + url); } else { port.postMessage("reusing connection to " + url); } } }, false); port.start(); }, false); 

我已经证实,这在Chrome 52中起作用。

不幸的是,最简单的解决scheme是在不改变SPA应用程序中的站点的情况下使用一个ServiceWorker,因为它在后台执行作业(也closures了选项卡),同时也解决了多个选项卡的问题。 我说“不幸”,因为他们仍然与大多数浏览器不兼容。 我自己find的唯一解决scheme是在服务器端对插槽通道进行分组,并创build一个队列来保存通过更改页面丢失的消息。 在这种情况下,你有一种虚拟的渠道。