【问题标题】:Access to signalr hub from other part of my application从我的应用程序的其他部分访问信号器集线器
【发布时间】:2021-10-06 07:27:48
【问题描述】:

我正在编写一个 blazor 服务器 Web 应用程序。

我已经编写了这个非常基本的信号器集线器:

using Microsoft.AspNetCore.SignalR;

public class MyHub: Hub
{
   public override Task OnConnectedAsync()
   {
      ...
      return base.OnConnectedAsync();
   }

   public Task my_function()
   {
      ...
   }
   ....
}

在这一步可以正常工作。

现在,我想从我的 blazor 应用程序的另一部分访问此中心:

public class AnotherClass
{
   private readonly IHubContext<MyHub> _hub;

   public AnotherClass(IHubContext<MyHub> hub)
   {
      _hub = hub;
   }

   ...
   
   public void another_function()
   {
      _hub.Clients.All.SendAsync(...); // <- This line works fine
      (_hub as MyHub).my_function();   // <- Does not work
   }
}

如您所见,我正在使用依赖注入来访问我的集线器对象。 我已经阅读了很多文档,包括微软的官方文档。 每个人都说我们必须在这种依赖注入中使用 IHubContext 类型。

所以 _hub 对象不知道 my_function 方法...

我尝试了很多东西:

  • 将 _hub 投射到 MyHub
  • 声明一个 IMyHub 接口并在依赖注入中使用 IMyHub

没有任何效果...

我的问题是:如何从 AnotherClass 对象调用 my_function ?

非常感谢

【问题讨论】:

    标签: dependency-injection signalr blazor signalr-hub


    【解决方案1】:

    我是这样做的。

    为您的集线器创建一个界面:

    public interface IMyHub
    {
        Task MyFunction(int parameter);
    }
    

    然后你的集线器实现这样的接口:

    public class MyHub : Hub<IMyHub>
    {
        public async Task MyFunction(int parameter)
        {
            // do stuff
        }
    }
    

    然后将集线器注入其他类,如下所示:

    private readonly IHubContext<MyHub, IMyHub> _myHub;
    

    您可以通过以下方式调用您的函数:

    _myhub.Clients.All.MyFunction(someInt);
    

    这是基于Strongly Typed HubsSend Messages From Outside a Hub 文档。

    添加到 IMyHUb 接口的函数不一定必须在 MyHub 类中有实现代码。例如,与

    public interface IMyHub
    {
        Task MyFunction(int parameter);
        Task MySecondFunction();
    }
    

    你可以在其他类中调用

    _myhub.Clients.All.MySecondFunction();
    

    在 MyHub 类中没有任何新代码。

    【讨论】:

    • 奇怪,是不是每个客户端都会调用MyFunction?
    • 这和_hub.Clients.All.SendAsync没有什么不同...集线器会将消息发送给所有连接的客户端
    • 您也可以调用Clients.GroupClients.AllExceptClients.User,就像使用弱类型集线器一样。
    • 事实上我想把逻辑放在集线器中,这是我想决定是否为一组、所有客户端等发送消息的地方。
    • 在集线器类的调用函数中,您仍然可以访问客户端和组等,并且可以调用您想要的任何部分。
    【解决方案2】:

    如何从 AnotherClass 对象调用 my_function ?

    你不能。仅在响应客户端调用时调用集线器。无法手动调用 hub 方法。

    如果您想在集线器内部和集线器外部运行逻辑,则需要重构代码,使其成为集线器和 AnotherClass 可以访问的某个共享类。

    【讨论】:

    • 是的,集线器是在客户端调用的上下文中设计的,因此它直接与特定客户端相关联。如果可以从任何地方任意调用集线器方法,您就会丢失有关客户端调用集线器方法的信息。这对于了解 connectionId、访问 Context.Items 以进行连接特定存储、Clients.Caller.SendAsync() 等非常有用。
    • 这是错误的我有一个从微服务后端调用客户端的应用程序。你注入一个 IHubContext
    • 调用客户端不同于从控制器等类手动调用集线器方法。我所说的一切都不反对从中心外致电客户。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多