了解SignalR-集线器、依赖注入和控制器



我一直在浏览文档和论坛,试图理解SignalR,但我很难理解。

我试图实现的是,在聊天应用程序中:将消息存储在Hub之外,这样每当用户加入聊天时,他们都可以看到在加入之前发送的所有消息。

所以看起来外部类是实现这一点的方法,所以我使用依赖注入

In ChatHub.cs
namespace SignalRChat.Hubs
{
public class ChatHub: Hub
{
public IChatStorage _chatStorage;
public ChatHub(IChatStorage chatStorage)
{
_chatStorage = chatStorage;
}
// and so on

我在ChatHub中有一个向chatStorage发送消息的方法,但我对如何将所有消息的列表从chatStorance发送回ChatHub,甚至发送回JavaScript感到困惑。看起来控制器是这样做的,但我不确定如何调用控制器的方法:

namespace SignalRChat.Controllers
{
public class ChatController: Controller
{
private IHubContext<ChatHub> _hubContext;
public ChatController(IHubContext<ChatHub> hubContext)
{
_hubContext = hubContext;
}
public void Send(List<Message> messages)
{
// to do: something where chatStorage calls this method, then this
// method uses _hubContext.Clients.All.SendAsync 
// But, how do I even call Send()???
}
}
}

从根本上说,我只是不明白如何把一切都连接起来。SignalR真的很令人困惑。

我了解简单的服务器集线器和客户端JavaScript关系是如何工作的。但是,通过依赖注入,我不明白为什么

public ChatHub(IChatStorage chatStorage)
{
_chatStorage = chatStorage;
}

工作。我没有更改任何代码,比如说新的ChatHub(新的IChatStorage(。微软的文档甚至说SignalR只调用默认的Hub构造函数。

在Startup.cs中,似乎没有任何内容表明我想用一个新的聊天存储调用ChatHub:

public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
services.AddSignalR();
services.AddSingleton<IChatStorage, ChatStorage>();
services.AddSingleton<ChatController>();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// omitted some default code
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
endpoints.MapHub<ChatHub>("/chatHub");
});
}

第一个问题是,这是怎么回事?它如何知道将参数传递给ChatHub构造函数?我了解服务。AddSingleton的部分,只是不是如何得到";有线连接";。

控制器类也是如此。程序如何知道将IHubContext对象传递到其构造函数中?你在哪里具体说明?

最后,您将如何进行此设置?当前我正在尝试从ChatHub进行通信->聊天存储->聊天控制器->聊天中心。为了做到这一点,我试图在chatStorage中传递一个对chatController的引用。

不确定是否清楚我在问什么。如果说有什么不同的话,我想找一个关于这些概念如何协同工作的清晰解释,而不是我的代码的具体解决方案。

谢谢!

那么第一个问题是,这是如何工作的?它如何知道将参数传递给ChatHub构造函数?我了解服务。AddSingleton的部分,只是不是如何得到";有线连接";。

SignalR实例化您的hub实例时(框架控制它,您不控制它(,它将解析hub构造函数中指定的任何依赖项。这是依赖注入系统的一部分,它是.NET的一部分(如注释中所述(。

控制器类也是如此。程序如何知道将IHubContext对象传递到其构造函数中?你在哪里具体说明?

同样的想法,但您不必连接IHubContext,这是AddSignalR所做的。

最后,您将如何进行此设置?当前我正在尝试从ChatHub进行通信->聊天存储->聊天控制器->聊天中心。为了做到这一点,我试图在chatStorage中传递一个对chatController的引用。

我不太清楚您希望客户端和服务器之间的交互是什么,以及集线器和控制器。

我试图实现的是,在聊天应用程序中:将消息存储在Hub之外,这样每当用户加入聊天时,他们都可以看到在加入之前发送的所有消息。

回到最初的声明,我可以问几个澄清的问题:

  • 当用户在聊天室中写消息时,您是在调用集线器还是控制器操作(REST API(?这将决定您需要在哪里注入IChatStorage类型。收到消息后,您将把消息隐藏在IChatStorage中
  • 当用户加入聊天时,他们会打电话到服务器以检索所有消息。此调用将返回存储在IChatStorage中的消息

假设您想对所有事情都使用集线器,那么您将在集线器上公开方法来实现这一点。如果您想使用来自客户端的REST API调用,那么您将使用控制器。

最新更新