在浏览器选项卡之间共享websocket

Sharing websocket across browser tabs?

本文关键字:共享 websocket 之间 浏览器 选项      更新时间:2023-09-26

我们希望每个浏览器有一个套接字,而不是浏览器中的每个选项卡有一个。我们如何才能做到这一点?我读到关于共享网络工作者的文章,这很有希望。我们也非常感谢您的参考。不幸的是,据我所知,mozilla或internetexplorer尚未实现共享网络工作者。那么在这种情况下该怎么办呢?我们正在服务器端开发node.js。

看到这个问题后,我终于实现了共享套接字,并在几天前添加到了我的库中。它似乎适用于大多数浏览器,甚至包括IE6,但Opera除外。对于Opera,您可以使用定期检查而不是卸载事件。

在上查看相关问题https://github.com/flowersinthesand/portal/issues/21

###留下cookie

  1. 设置cookie以通知存在共享套接字
  2. 当套接字关闭时,删除该cookie以通知没有共享套接字

参见,https://github.com/flowersinthesand/portal/blob/7c2ce4bb61d05d80580e6cde6c94a78238a67345/jquery.socket.js#L629-L650

###共享和使用共享套接字

  1. 使用存储事件和localStorage-当设置并删除某个值时,localStorage会触发存储事件
  2. 请检查是否支持StorageEvent和localStorage
  3. 添加按键筛选事件的存储事件处理程序。我使用了套接字的url作为密钥
  4. 添加删除存储属性的套接字的关闭事件
  5. 要发出信号,请使用前一个键将数据设置为存储

共享:https://github.com/flowersinthesand/portal/blob/7c2ce4bb61d05d80580e6cde6c94a78238a67345/jquery.socket.js#L531-L568

使用共享:https://github.com/flowersinthesand/portal/blob/7c2ce4bb61d05d80580e6cde6c94a78238a67345/jquery.socket.js#L851-L893

  1. 使用window.open方法-如果我们知道共享窗口的名称,我们可以获取该窗口的引用并访问其属性
  2. 每个浏览器都支持window.open方法,但有些浏览器(如Chrome)禁止访问返回窗口的属性
  3. 获取或创建名称属性为键的iframe。我使用了socket的url,但注意IE不允许在iframe标记的name属性中使用非单词字符
  4. Iframe的contentWindow是一个共享窗口引用。设置回调变量以存储每个窗口的侦听器
  5. 要发出信号,只需使用数据调用回调即可。注意,IE 8及以下版本只允许将字符串传递给其他窗口的函数,并且共享窗口可以被销毁

共享:https://github.com/flowersinthesand/portal/blob/7c2ce4bb61d05d80580e6cde6c94a78238a67345/jquery.socket.js#L571-L605

使用共享:https://github.com/flowersinthesand/portal/blob/7c2ce4bb61d05d80580e6cde6c94a78238a67345/jquery.socket.js#L894-L929

备注

  1. 在上述实现中,信令是广播的,因此数据应该指示目标。我使用了target属性,p表示parent,c表示child
  2. 我使用了额外的变量来共享套接字:opened-共享套接字是否打开,children-sharer列表。代码和注释将帮助您了解详细信息

我希望我的回答有帮助。

在某些情况下,我使用localStorage对象在选项卡之间进行通信。localStorage对象有一个事件系统,用于告诉同一来源的另一个选项卡或窗口某些数据已更改(http://www.codediesel.com/javascript/sharing-messages-and-data-across-windows-using-localstorage/)。其想法是,让带有套接字的选项卡将时间戳和接收到的数据写入本地存储。如果时间戳太旧——可能是因为带有套接字的选项卡已经关闭——另一个选项卡可以启动套接字连接并更新数据和时间戳。

2016年的答案必须是本博客中描述的共享网络工作者:

https://blog.pusher.com/reduce-websocket-connections-with-shared-workers/

我使用localStorage作为共享通信通道,以便使用与EventEmitters相同的接口在选项卡之间发送数据。再加上决定哪个选项卡将连接到服务器的领导者选举算法,我将所有套接字事件从所有跟随者选项卡中继到领导者选项卡,反之亦然。最后,leader选项卡将所有事件转发到服务器,并将所有接收到的事件广播到所有其他客户端。这是代码:

  • https://github.com/majestic3/athena-online-judge/blob/master/source/client/core/itc.js
  • https://github.com/majestic3/athena-online-judge/blob/master/source/client/core/socket.js

远非理想,但您可以使用闪存本地连接来设置一个websocket连接,然后在选项卡和多个浏览器之间共享。

请参阅http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/net/LocalConnection.html?filter_flash=cs5&filter_flashplier=10.2&filter_air=2.6以获取更多信息。

我仍在为我准备开始构建的设计进行理论化。但是,我正在考虑合并

-WebSockets-本地存储和-跨窗口消息

我的理论是用javascript创建一个套接字引擎,该引擎在每个选项卡的每个页面加载时运行,但如果已经建立了连接,就会关闭。

第一次访问该网站时,我会让它生成一个GUID并将其存储在本地存储中,该GUID将唯一标识用户浏览/登录到他们的电脑。

当套接字服务器接受连接时,它将具有该guid,并且该guid发出的任何新请求都将返回"999 connection Already Established"或类似的信息。

一旦运行,它将通过跨窗口消息为其他选项卡播种,方法是将我想在跨选项卡中共享的数据转换为JSON blob,然后在其他选项卡中接收到数据时将其转换回对象。因此,无论哪个选项卡是连接,都将使用套接字服务器处理所有传入/传出消息。然后,它将通过跨窗口消息与其他选项卡进行接收/传输。理论上,这应该也适用于Iframe和Popup窗口。

整个系统将为我们正在构建的类似CRM的系统以及实时聊天系统和售票板驱动加载表单的自动数据刷新。

我的梦想场景是,如果用户A盯着票证1000,而用户B更新票证1000,我希望用户A的票证刷新,并且如果用户A在刷新之前进行了更改,我希望给他们一个数据迁移弹出窗口,以防止吹走用户B更改的

--用户B在您编辑此记录时进行了冲突更改"用户B:FirstName->Bob"[Take]"UserA:FirstName->Robert"[Keep]

不要认为现在有一个解决方案可以实现socket.io。看看这段视频中的吉列尔莫·劳赫,第五段。他也认为这是一个挑战。

请参阅https://github.com/nodeca/tabex

您需要额外的层来进行跨选项卡通信。Tabex有王菲使用的例子。其他websocket传输(socket.io等)也可以以类似的方式使用。

实际上,很难避免其中的一些问题,例如:在网络不稳定时断开连接。毕竟,页面最初的目的是交换不同的文本文档(如RFC文档),这只需要一种短、低成本和不稳定的传输方法(我认为建立HTTP协议的最初目的)

当然,为了解决这个问题,我建议你像上面说的那样使用共享工作者,或者用LocalStorage 存储共享和公共部分的信息

以下是LocalStorage 基本用法介绍的链接

希望它能真的希望你!(实际上还没有)