我做了一个简单的应用程序与SignalR进行测试。 当页面加载它调用服务器上的功能,该功能然后调用打印屏幕上的消息客户端功能。 我这样做是为了检查客户端和服务器功能的工作原理和SignalR通信工程确定。
我的问题是,如果我打开两个不同的标签相同的页面(在Chrome中做到了),在第一页加载好了,但第二页不会调用服务器的功能 - 只有当我关闭的第一页。
所以,据我了解,他们很可能是有关不允许SignalR连接更多然后一次(实际上是两个,一个用于接收,一个用于发送)浏览器的连接限制
更新:我已经找到我们其他的标签,其中开放,但现在我已经通过检查,它仅允许4个选项卡 /页,与连接活跃。 如果我试图把在同一个页面一个新的标签没有数据发送,当我关闭其他标签的一个上,新标签发送数据的时候了。
我想知道是否有对任何解决办法,因为我想这个连接可用,如果用户决定要打开两个标签或更多相同的页面。
我不认为这有什么用IIS,因为我知道它可以接受数千个连接。
这个问题将通过将来最好寻址通道消息规范,它并没有被任何浏览器的最新实现,但我设法解决这个问题限制连接的数目作为由Alex福特描述和使用localStorage
作为间消息总线标签。
该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的(亚历克斯提供)通知其他选项卡,以防止重复localStorage.setItem
电话。
Facebook的克服了在多个子域名服务的持续连接这项浏览器限制,但是这可能复杂化的部署和测试。
注意事项
旧的连接:在Alex的解决方案,你需要小心的Disconnect()
没有被调用(如异常),并且你填满你的HubConnections
桶(或仓库)与老集线器连接。 如果会话ID没有变化(可能发生的),这可能会阻止新的客户端无法建立,即使没有被激活一个SignalR连接。 另外,时间戳新的连接,并有一个滑动过期,以尽量减少可能产生的影响。
锁定: localStorage
可能会受到种族条件,因为它没有实现任何锁定这里描述 。
为了支持不同类型的事件,你应该编码在你的JSON消息是为它的EVENTTYPE和测试storage
事件。
回退
如果SignalR连接不能建立,我回落到轮询服务器每45秒检索通知计数。
如果你不希望使用本地存储,您可以使用Cookie,但它不是那么干净。
为了扩大对@ FreshCode的答案,这是我如何实现他的想法。
我有一个需要通过标签之间的两个不同的动作。 我可以设置通知或删除通知。 这些通知是由浏览器接收和超时,将火在指定的时间保存。 第一个选项卡有SignalR连接和所有的其他人没有。 有一个问题我必须克服的是,“存储”事件将火无论哪个动作,我想要执行(设置/删除)。
最后我做随着含我想执行的操作的属性自定义JSON对象路过什么:
$(window).bind('storage', function () {
var updateInfo = JSON.parse(localStorage.getItem('updateInfo'));
if (updateInfo.action == 'removeNotification')
removeNotification(updateInfo.notificationId);
else if (updateInfo.action == 'setNotification')
setNotification(updateInfo.notification);
});
这每一次我在本地存储设置的项目来说,我只是指定需要发生,仅会发生在其他标签动作的动作。 例如,如果我更新的通知它既是动作的组合时,由客户端接收。 它消除了通知,并设置与更新的值的通知。 因此,要两个呼叫localStorage.setItem
正在作出。
function removeNotification(id) {
// Check if signalR is connected. If so, I am the tab that will update
// the other tabs.
if ($.connection.hub.state === 1) {
var updateInfo = {
action: 'removeNotification',
notificationId: id
};
localStorage.setItem('updateInfo', JSON.stringify(updateInfo));
}
// brevity brevity
}
同样, setNotification
功能。
function setNotification(notification) {
if ($.connection.hub.state === 1) {
var updateInfo = {
action: 'setNotification',
notification: notification
};
localStorage.setItem('updateInfo', JSON.stringify(updateInfo));
}
// brevity brevity
}
我创建了IWC万国表SignalR工具,它允许对同一应用程序的所有窗口(标签)单SignalR连接。
这个怎么运作
一个窗口的成为连接所有者(随机choosen)并保持真实SignalR连接。 如果连接所有者被关闭或崩溃的另一个窗口变成一个连接者 - 这是自动发生。 间窗口的通信是通过来完成的窗口间通信库 (基于localStorage
)。 该库提供的功能并行处理(锁,共享数据,事件总线...)之间的窗口之间进行通信。 希望这将是有用的人。