SignalR和浏览器连接限制

Ida*_*ter 16 asp.net iis push-notification signalr

我用SignalR做了一个简单的应用程序进行测试.当页面加载它调用服务器上的函数时,该函数然后调用在屏幕上打印消息的客户端函数.我这样做是为了检查客户端和服务器功能是否正常以及SignalR通信是否正常.

我的问题是,如果我在两个不同的选项卡上打开相同的页面(在Chrome中执行),第一页加载正常,但第二页不会调用服务器的功能 - 仅在我关闭第一页时.

所以据我所知,他们可能是一个与浏览器有关的连接限制,它不允许SignalR多次连接(实际上是两个,一个用于接收,一个用于发送)

更新:我发现我们的其他选项卡处于打开状态,但现在我已经检查了它,它只允许4个选项卡 /页面处于活动状态.如果我尝试将相同的页面放在新选项卡上,则不会发送任何数据,当我关闭其中一个选项卡时,新选项卡会立即发送数据.

我想知道是否有任何解决方案,因为如果用户决定在两个或更多选项卡上打开相同的页面,我希望此连接可用.

我不相信它与IIS有任何关系,因为据我所知,它可以接受数千个连接.

Pet*_*ron 18

未来的Channel Messaging规范最好解决这个问题,迄今为止还没有被任何浏览器实现,但我设法通过限制 Alex Ford所描述的连接数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+')'
        );
});
Run Code Online (Sandbox Code Playgroud)

您可以测试if ($.connection.hub.state === 1)以确定给定选项卡是否应通过localStorage(由Alex提供)通知其他选项卡以防止重复localStorage.setItem调用.

Facebook通过在多个子域上提供持久连接来克服此浏览器限制,但这可能使部署和测试复杂化.

注意事项

旧连接:在Alex的解决方案中,您需要注意Disconnect()不要被调用(例如异常),并HubConnections使用旧的集线器连接填充您的存储桶(或存储库).如果会话ID没有改变(可能发生),这可能会阻止新客户端建立SignalR连接,即使它们都没有活动.或者,为新连接添加时间戳并具有滑动到期时间以最小化潜在影响.

锁定: localStorage可能会受到竞争条件的影响,因为它没有实现此处所述的任何锁定.

要支持不同类型的事件,您应该在JSON消息中编码eventType并在storage事件上对其进行测试.

回退

如果无法建立SignalR连接,我将回到每45秒轮询一次服务器以检索通知计数.

如果您不想使用localStorage,您可以使用cookie,但它不是那么干净.

  • 给这个男人一枚奖牌,或至少一个绿色的复选标记! (3认同)
  • 我开始实现这个localStorage行为,然后意识到我仍然需要一种方法来限制连接到一个.我知道我是如何使用数据库做的,但我回到这个答案,看看它是如何在这里完成的.直到那时我才意识到他与我自己的博客文章有关.哈哈 (3认同)