如何维护页面之间的WebSockets连接?

时间:2012-06-04 19:13:36

标签: javascript html websocket

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

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

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

我试图将window.ws放在全局范围内但似乎没有解决问题。 WebSockets连接是否有任何方法可以在页面之间保留,因此不需要不断重新建立连接?

4 个答案:

答案 0 :(得分:24)

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

另一种旧方法可以将您的页面放在一个框架中,用户只能在框架中导航(即使它占据了窗口的整个大小)。通过这种方式,您可以在最顶层的窗口中创建WebSocket,永远不会更改(这也意味着位置栏中显示的URL将始终相同)。

说,我同意@dystroy:你的应用程序应该始终能够处理这种情况 - 用户可能会遇到一些网络问题并暂时失去连接,即使它没有离开页面。

答案 1 :(得分:19)

您可以尝试在共享WebWorker中创建WebSocket连接,该连接允许来自同一域的多个页面共享执行上下文。但是,目前还不清楚共享工作者是否会在页面重新加载或替换时保持不变:Do Shared Web Workers persist across a single page reload, link navigation

此外,共享WebWorkers目前有limited browser support(webkit和Opera)。

<强>更新

由于单个共享Web工作者可以提供多个页面,因此实现比普通Web工作者稍微复杂一些。

这是一个共享的Web worker示例,它使用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中实现共享工作者的Javascript:

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。

答案 2 :(得分:1)

不幸的是,只使用一个ServiceWorker就可以获得最简洁的解决方案,而无需在SPA应用程序中更改您的站点,因为它可以在后台完成工作(也可以关闭选项卡)并且它还可以解决多个选项卡的问题。我说“不幸”,因为它们仍然与大多数浏览器不兼容。 我自己发现的唯一解决方案是在服务器端对套接字通道进行分组,并创建一个队列,以便通过更改页面来保留丢失的消息。在这种情况下,您有一些虚拟通道。

答案 3 :(得分:-2)

您可以在本地存储中记录与websocket服务器的对话,该对话在页面加载期间仍然存在。