28

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

例如:

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

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

4

3 回答 3

28

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

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

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

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

于 2014-03-03T15:50:55.247 回答
14

要从 Hubs 开始,请阅读WIKI 条目中的 Hubs and Client Side of Hubs。根据多个页面的上下文,有几件事。

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

例子:

你有一个页面,它有两个部分,一个显示实时用户活动的图表和一个以表格形式查看用户所做的实时数据更改的区域。你会创建两个集线器或两个组还是什么?还有其他页面使用相同的图表和数据表。

我的解决方案:

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

当您在页面之间切换时,客户端将连接到同一个集线器并请求 getGraph 或 getDataTable 或两者并用相关数据填充其客户端。同样,在服务器上,当数据更改时,您可以调用客户端方法来更新所有客户端或一组客户端(让我们增加这种复杂性)

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

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

回到您的“是否不好”和“还可以”的问题,如果没有实际应用的上下文,这很难确定。我想不出一个场景,你可以证明除Performance之外的多个集线器是合理的。

于 2012-12-29T15:07:01.320 回答
13

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 并不一定是一项微不足道的任务。


那么如何修复呢?

首先(暂时)将您的集线器设置为仅接受 websocket。这将在 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。这对我来说不是一个选项,因为我使用 Facebook / Google / Payment 等某些 API,并且它们需要 https。

笔记

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

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

如何在没有用户交互的情况下在 Windows 10 中创建和安装 X.509 自签名证书?

于 2019-01-21T07:22:47.917 回答