从我的应用程序的其他部分访问信号器集线器

问题描述

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

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

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 ?

非常感谢

解决方法

我是这样做的。

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

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 类中没有任何新代码。

,

如何从 AnotherClass 对象调用 my_function ?

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

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