这个问题最好在未来得到解决频道消息传递 http://www.whatwg.org/specs/web-apps/current-work/multipage/web-messaging.html#channel-messaging规范,迄今为止尚未被任何浏览器实现,但我设法通过以下方式解决了它限制连接数 http://www.codetunnel.com/cannot-have-many-tabs-open-with-signalr正如亚历克斯·福特所描述的并使用localStorage
作为选项卡之间的消息总线。
The storage
事件允许您在选项卡之间传播数据,同时保持单个 SignalR 连接打开(从而防止连接饱和)。呼唤localStorage.setItem('sharedKey', sharedData)
将提高storage
所有其他选项卡中的事件(不是调用者):
$(window).bind('storage', function (e) {
var sharedData = localStorage.getItem('sharedKey');
if (sharedData !== null)
console.log(
'A tab called localStorage.setItem("sharedData",'+sharedData+')'
);
});
你可以测试if ($.connection.hub.state === 1)
确定给定选项卡是否应通过 localStorage 通知其他选项卡(由 Alex 提供)以防止重复localStorage.setItem
calls.
Facebook 通过在多个子域上提供持久连接来克服此浏览器限制,但这可能会使部署和测试变得复杂。
Caveats
旧连接:在Alex的解决方案中,你需要小心Disconnect()
没有被调用(例如例外),并且您填写了您的HubConnections
具有旧集线器连接的存储桶(或存储库)。如果会话 ID 没有更改(可能会发生),这可能会阻止新客户端建立 SignalR 连接,即使没有活动的连接。或者,为新连接添加时间戳并设置滑动过期时间,以最大程度地减少潜在影响。
Locking: localStorage
可能会受到竞争条件的影响,因为它没有实现任何锁定此处描述 http://balpha.de/2012/03/javascript-concurrency-and-locking-the-html5-localstorage/.
为了支持不同类型的事件,您应该编码事件类型在您的 JSON 消息中并对其进行测试storage
event.
后备措施
如果无法建立 SignalR 连接,我会每 45 秒轮询一次服务器以检索通知计数。
如果你不想使用localStorage,你可以使用cookie,但它不太干净。