您网站上的多个signalR连接/集线器

时间:2012-08-01 17:21:12

标签: c# asp.net signalr

如果我有多个可以使用多个集线器类的页面,那么管理它的最佳方法是什么?

例如:

  • 导航到网站中的其他页面并且基本上“重新打开”与上一页打开的同一个集线器类的连接是不是很糟糕?

  • 我是否认为在页面上打开多个集线器连接是正确的,因为它们在一个连接中都是统一的,即使它们是不同的集线器类?

3 个答案:

答案 0 :(得分:24)

您可以让多个集线器在您的网站上共享一个连接。 SignalR 2.0已更新,可通过一个signlar连接处理多个集线器,而不会丢失性能。

官方文档:http://www.asp.net/signalr/overview/signalr-20/hubs-api/hubs-api-guide-server#multiplehubs

  

所有客户端都将使用相同的URL与您的服务建立SignalR连接(“/ signalr”或您指定的自定义URL),并且该连接用于该服务定义的所有集线器。

     

与在单个类中定义所有Hub功能相比,多个Hub没有没有性能差异。

答案 1 :(得分:9)

从Hub开始,请阅读WIKI entry for HubsClient Side of Hubs。根据多页的上下文,有几件事情。

  1. 当您启动集线器时,它会为您的客户提供一个ID,该ID在多个页面上与该集线器保持一致(有人可以通过示例确认)。
  2. 重新打开与同一个集线器的连接并不错。您可能在所有页面上运行hub.start客户端方法,但是如果其中一个客户端打开多个窗口或从一个页面转到另一个页面,则该集线器上将具有相同的连接ID,以便您可以保持联系。如果它是多个集线器,那么您必须管理集线器以及连接ID。所以这个问题就像是“为不同的网站提供多个ISP服务我的互联网连接是不是很糟糕”。你可以拥有它们,但它是一种矫枉过正。一个ISP也可以为您提供所有页面服务。
  3. 单个页面上的多个集线器并不理想,但它可以正常工作。同样,答案需要一些问题的上下文,但一般来说,您可以通过组或使用其他基于参数的方法区分相同连接ID上的各种请求。在同一页面上使用两个集线器可能需要更多资源(需要测试此内容),而不是使用参数或组来分隔不同的消息传递区域。
  4. 示例:

    您有一个包含两个部分的页面,一个显示实时用户活动的图表和一个区域,用于查看用户作为表格执行的实时数据更改。你会创建两个集线器或两个组或什么?还有其他页面使用相同的图形和数据表。

    我的解决方案:

    1. 我将为应用程序创建一个集线器,以便从服务器接收实时数据。
    2. 我将在服务器上创建不同的方法来发送图形点和数据表。
    3. 我将在所有使用这些图表与同一集线器上的服务器方法进行通信的页面上创建客户端方法。
    4. 当您在页面之间切换时,客户端将连接到相同的集线器并请求getGraph或getDataTable或两者并使用相关数据填充其客户端。同样在服务器上,当数据发生变化时,您可以调用客户端方法来更新所有客户端或组中的(让我们添加这种复杂性)

      假设您有学生和老师查看您的申请。它们需要不同级别的数据访问。您可以使用群组在群集中将它们分开,这样您就不会向教师发送教师信息给学生和学生数据。

      1. 在您的集线器加入中,您可以添加它们以加入与其角色或任何差异化功能相关联的组。
      2. 当您发送给所有客户时,现在您可以发送给教师或学生的客户群。没有为教师或学生创建另一个中心,他们都在同一个中心。
      3. 回到你的“不好”和“没问题”的问题,如果没有实际应用的背景,这很难建立。我不能想到除了Performance之外你可以证明多个集线器的合理性。

答案 2 :(得分:3)

SignalR核心-不可能

不幸的是,在SignalR的新“核心”版本中这不再可行

https://github.com/aspnet/SignalR/issues/456

https://github.com/aspnet/SignalR/issues/955


注意:iOS和自签名证书存在问题

在iOS上,每个服务器最多只能有四个连接。

现在,网络套接字没有这个限制(我认为可能是32个,但不确定)。 但是,我使用的是自签名证书,该证书在Safari中存在各种问题-因此它实际上可以归结为长时间轮询(而且这样做并不明显)。

所以我最终得到了这些连接:

  • 1-Angular / Webpack热装插座
  • 2-Web API调用
  • 3-第一枢纽
  • 4-第二号集线器
  • 5-&#&#$ &#$

因此,如果我只有三个集线器,则整个Safari页面将被蓝色条锁定。甚至Web API调用也被阻止。

注意:使用HTTP / 2 this limit is gone,但最好将自己限制为一个集线器,尤其是在使用热重装的情况下。此外,在开发过程中设置HTTP / 2不一定是一项琐碎的任务。


那怎么解决?

首先(临时)将集线器设置为仅接受网络套接字。这将使您在Safari中出现错误(请确保已捕获错误并在警报对话框中显示该错误)。

routes.MapHub<SignalRHub>("/rt", options =>
{
     // when run in debug mode only WebSockets are allowed
     if (Debugger.IsAttached) {
        options.Transports = Microsoft.AspNetCore.Http.Connections.HttpTransportType.WebSockets;
     }
});

现在,您将能够确认修复-以调试模式运行,或删除“ if”。

iOS的问题是,即使您接受针对https流量的自签名证书-并在浏览器中获得一个漂亮的小“锁”符号-它不适用于wss:协议。因此无法将连接升级到wss,这就是为什么它们最多阻塞4个的原因。

解决方案#1

如果您可以将所有内容集中到一个集线器,那就更容易了:-)

我还意识到,如果连接断开,多个集线器会使重新连接逻辑复杂化。一个集线器使此操作变得更容易。如果不小心,最终将显示3个对话框,提示“连接丢失。重试?'正因为如此,我才切换到单个集线器。

虽然我讨厌混合所有内容,但局部类会有所帮助,而且我个人也没有很多SignalR方法。

解决方案2

这仅与调试有关,并假定您使用的是自签名的https证书。

请改用letencrypt-或Cloudflare的argo隧道之类的方法来获取公众信任的证书。 Safari将完全信任它,因此您的连接将升级到真实的Web套接字。

解决方案#3

创建一个自签名的ROOT证书(CA),然后使用其中的域名生成SSL证书。

这比我想象的要难。最后,事实证明,我的根证书中缺少Subject Type=CA-iOS要求。没有此“扩展名”,它将把根证书作为配置文件安装到您的根目录,但不允许您为SSL选择它。

一旦您安装了根证书,Safari就可以与websockets一起正常工作。

解决方案#4

仅使用http。这不是我的选择,因为我使用了某些API,例如Facebook / Google / Payment,并且它们需要https。

注释

  • 重要:现在考虑生产。请注意,由于各种原因,websocket可能不可用,因此,如果您在iOS上连接了4个集线器,则仍然可能导致阻塞。你过着危险的生活。

最好首先使用一个集线器。但最好还是正确安装证书,以便iOS可以与websockets一起使用。

How to create and install X.509 self signed certificates in Windows 10 without user interaction?