gpt4 book ai didi

c# - SignalR 多个集线器在同一应用程序的不同路径上?

转载 作者:太空宇宙 更新时间:2023-11-03 10:58:48 34 4
gpt4 key购买 nike

我有一个包含多个集线器的应用程序,所有集线器都位于唯一路径上,因此在调用默认值时:

routes.MapHubs("path", new HubConfiguration(...));

它爆炸说 signalr.hubs 已经定义(如此处所述 MapHubs not needed in SignalR 1.01? )。

现在我明白它应该只被调用一次,但是你只会得到 1 条路径,那么有没有办法处理每个集线器场景的路径?就像你如何使用 MVC 指定 Controller 和 Action ?所以像这样:

routes.MapHub<SomeHub>("path", new HubConfiguration(...));

== 编辑更多信息==

经常提到您永远不需要多次调用此 map 中心,在大多数情况下我同意,但我不会说这将是所有应用程序。

在这种情况下,它是一个在运行时加载任何可用插件的网站,每个插件都暴露在依赖注入(inject)框架中以包含其依赖项和路由表以包含其路由。集线器可能彼此无关(除了它们都是集线器对象这一事实)。所以这些集线器并不是预先都知道的,只有在加载插件后才知道,是的,我可以等到这之后尝试绑定(bind)那里的集线器,但是那时我如何为每个集线器设置自定义路由?

这似乎是 SignalR 试图抽象得太多的一个例子,因为我不认为拥有自定义路由而不是默认的“/signalr”是一个坏主意,并且由于路由都有不同的职责它为他们所有人提供一条进入路线似乎很糟糕。

所以无论如何我认为这个问题仍然存在,因为我不认为这是一个糟糕的用例或糟糕的设计它似乎只是我希望能够有一个应用了集线器的路由,就像在 mvc 中,您将 Controller 和操作应用于路由。

最佳答案

您只需要 signalr.hubs 路由即可。如果将浏览器指向该路由,您会看到它会自动找到所有可分配给 IHub 的公共(public)类型,并为它们创建一个 JavaScript 代理。您可以通过 JavaScript 通过名称与不同的集线器进行交互,即如果您有以下集线器:

public class GameHub : Hub

您可以通过以下方式连接到该特定集线器:

var gameHubProxy = $.connection.gameHub;

您还可以通过将 HubNameAttribute 添加到类中来明确指定您的集线器的名称:

[HubName("AwesomeHub")]
public class GameHub : Hub

然后您可以通过执行以下操作来检索特定的代理

var awesomeHubProxy = $.connection.awesomeHub;

更新:

我不确定 SignalR 是否能够在同一应用程序的多个路径上运行。它可能会把事情搞砸,而且默认程序集定位器无论如何都无法拾取在运行时加载的集线器。

但是,有一个解决方案,您可以在其中实现自己的 IAssemblyLocator,它将从您的插件程序集中获取集线器:

public class PluginAssemblyLocator : DefaultAssemblyLocator
{
private readonly IEnumerable<Assembly> _pluginAssemblies;

public PluginAssemblyLocator(IEnumerable<Assembly> pluginAssemblies)
{
_pluginAssemblies = pluginAssemblies;
}

public override IList<Assembly> GetAssemblies()
{
return base.GetAssemblies().Union(_pluginAssemblies).ToList();
}
}

加载插件后,您应该调用 MapHubs 并注册 SignalRs IAssemblyLocator 服务的覆盖:

protected void Application_Start(object sender, EventArgs e)
{
// Load plugins and let them specify their own routes (but not for hubs).
var pluginAssemblies = LoadPlugins(RouteTable.Routes);

RouteTable.Routes.MapHubs();

GlobalHost.DependencyResolver.Register(typeof(IAssemblyLocator), () => new PluginAssemblyLocator(pluginAssemblies));
}

注意:注册 IAssemblyLocator AFTER 你调用了 MapHubs 因为它也会覆盖它。

现在,这种方法存在问题。如果您使用的是静态 JavaScript 代理,它不会在每次访问时都重新生成。这意味着如果您的 /signalr/hubs 代理在所有插件/集线器加载之前被访问,它们将不会被拾取。您可以通过确保在映射路由时加载所有集线器或根本不使用静态代理来解决此问题。

此解决方案仍然需要您获得对插件程序集的引用,我希望这是可行的...

关于c# - SignalR 多个集线器在同一应用程序的不同路径上?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18465964/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com