问题描述
我正在编写一个 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 Hubs 和 Send 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 可以访问的某个共享类。