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

Javascript 如何维护页面之间的WebSocket连接?,javascript,html,websocket,Javascript,Html,Websocket,在我的一个脚本中,我有以下代码: var webSocket = window.WebSocket || window.MozWebSocket; window.ws = new webSocket('ws://64.121.210.140:2585/consoleappsample', 'my-protocol'); 这很好用。但是,当用户更改页面时,我必须重新建立连接。我认为这会在我的代码中造成问题,因为如果客户端向服务器发送数据,然后更改页面,则可能无法接收数据,并且会发生争用情况 我试

在我的一个脚本中,我有以下代码:

var webSocket = window.WebSocket || window.MozWebSocket;
window.ws = new webSocket('ws://64.121.210.140:2585/consoleappsample', 'my-protocol');
这很好用。但是,当用户更改页面时,我必须重新建立连接。我认为这会在我的代码中造成问题,因为如果客户端向服务器发送数据,然后更改页面,则可能无法接收数据,并且会发生争用情况


我试图将
window.ws
放在全局范围内,但似乎没有解决问题。有没有办法让WebSockets连接在页面之间保持不变,这样就不需要不断地重新建立连接?

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

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


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

您也可以尝试在共享WebWorker中创建WebSocket连接,该连接允许来自同一域的多个页面共享执行上下文。但是,不清楚共享工作区是否在页面重新加载或替换过程中持续存在:

此外,共享WebWorkers(webkit和Opera)目前也有

更新

由于单个共享web工作人员可以服务多个页面,因此实现比普通web工作人员稍微复杂一些

下面是一个共享web worker示例,它使用WebSocket并可以在

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

我已经在Chrome 52中验证了这一点。

不幸的是,在SPA应用程序中使用一个ServiceWorker就可以获得最干净的解决方案,而无需更改您的站点,因为它可以在后台完成工作(也可以关闭选项卡),并且还可以解决多个选项卡的问题。我说“很遗憾”,因为它们仍然与大多数浏览器不兼容


我自己找到的唯一解决方案是在服务器端对套接字通道进行分组,并创建一个队列来保存因更改页面而丢失的消息。在这种情况下,您有一种虚拟通道。

您可以将与websocket服务器的对话记录在localstorage中,这会在页面加载时保持不变

我不这么认为。但是应用程序逻辑应该涵盖连接问题。使用框架技巧,有没有办法让地址栏中的位置反映包含可导航内容的框架中的导航位置?自动地如果内容中的链接保持普通的hrefs?您可以尝试使用。我知道这是一个旧的答复,但如果应用程序的用户总是更改页面,这不会不断断开和重新连接web套接字服务器吗?我有疑问。webworkers中没有websocket支持。在这种情况下,我们如何维护应用程序的上下文。@kongaraju,您可以通过Chrome中的webworkers使用websocket,Firefox中有一个Mozilla bug实现对它的支持:@kongaraju,我刚刚添加了一个示例,我已经验证了它在Chrome 20中可以正常工作,并且确实从共享WebWorker与服务器建立了WebSocket连接。它缺乏跨浏览器的支持。@Shkarbatovdmitry我刚用Chrome 52试用过,它按预期工作(刷新单页重新创建,刷新两页中的一页导致重复使用)。请注意,您需要修改我的示例以将websocket连接状态存储在连接处理程序之外。此外,您的页面和websocket目标可能需要位于localhost之外的其他位置。
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);