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

ant*_*liu 22 c# asp.net signalr

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

例如:

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

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

Sam*_*Sam 25

您可以让多个集线器在您的站点上共享一个连接.SignalR 2.0已更新,可通过一个signlar连接处理多个集线器,性能不会下降.

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

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

多个集线器没有性能上的差异相比,在一个类中定义的所有集线器功能.


Far*_*ani 10

要开始使用集线器进行阅读的集线器WIKI进入枢纽进行客户端.根据多页的上下文,有几件事情.

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

例:

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

我的解决方案

  1. 我将为应用程序创建一个集线器,以便从服务器接收实时数据.
  2. 我将在服务器上创建不同的方法来发送图形点和数据表.
  3. 我将在所有使用这些图表与同一集线器上的服务器方法进行通信的页面上创建客户端方法.

当您在页面之间切换时,客户端将连接到相同的集线器并请求getGraph或getDataTable或两者并使用相关数据填充其客户端.同样在服务器上,当数据发生变化时,您可以调用客户端方法来更新所有客户端或其中的一(允许添加此复杂性)

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

  1. 在您的集线器加入中,您可以添加它们以加入与其角色或任何差异化功能相关联的组.
  2. 当您发送给所有客户时,现在您可以发送给教师或学生的客户群.没有为教师或学生创建另一个中心,他们都在同一个中心.

回到你的"不好"和"没问题"的问题,如果没有实际应用的背景,这很难建立.我不能想到除了Performance之外你可以证明多个集线器的合理性.

  • 你的第二点正是我正在寻找的,多次调用 `$.connection.hub.start()` 并没有什么坏处 (2认同)

Sim*_*ver 9

SignalR核心-不可能

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

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

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


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

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

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

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

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

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

注意:使用HTTP / 2时,此限制已消失,但最好将自己限制为一个集线器,尤其是在使用热重载时。另外,在开发中设置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;
     }
});
Run Code Online (Sandbox Code Playgroud)

现在,您将能够确认修复-以调试模式运行,或删除“ 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一起使用。

如何在Windows 10中创建和安装X.509自签名证书而无需用户交互?