SignalR:如何在 ASP.NET MVC 中使用 IHubContext<THub,T> 接口?

6 c# asp.net-mvc dependency-injection signalr

Microsoft.AspNet.SignalR我一直在尝试在使用库的ASP.NET MVC 项目中使用以下方法:

public interface ITypedHubClient
{
  Task BroadcastMessage(string name, string message);
}
Run Code Online (Sandbox Code Playgroud)

继承自集线器:

public class ChatHub : Hub<ITypedHubClient>
{
  public void Send(string name, string message)
  {
    Clients.All.BroadcastMessage(name, message);
  }
}
Run Code Online (Sandbox Code Playgroud)

将类型化的 hubcontext 注入到控制器中,并使用它:

public class DemoController : Controller
{   
  IHubContext<ChatHub, ITypedHubClient> _chatHubContext;

  public DemoController(IHubContext<ChatHub, ITypedHubClient> chatHubContext)
  {
    _chatHubContext = chatHubContext;
  }

  public IEnumerable<string> Get()
  {
    _chatHubContext.Clients.All.BroadcastMessage("test", "test");
    return new string[] { "value1", "value2" };
  }
}
Run Code Online (Sandbox Code Playgroud)

但是,库中没有IHubContext<THub,T>接口Microsoft.AspNet.SignalR,因此我无法使用IHubContext两个参数(IHubContext<ChatHub, ITypedHubClient> _chatHubContext;)。所以,我想知道是否可以使用 DI 库或方法。如果是这样,如何解决这个问题?

Ale*_*der 7

Microsoft.AspNetCore.SignalR包含IHubContext无类型集线器

public interface IHubContext<THub> where THub : Hub
{
    IHubClients Clients { get; }
    IGroupManager Groups { get; }
}
Run Code Online (Sandbox Code Playgroud)

对于类型集线器

public interface IHubContext<THub, T> where THub : Hub<T> where T : class
{
    IHubClients<T> Clients { get; }
    IGroupManager Groups { get; }
}
Run Code Online (Sandbox Code Playgroud)

正如您从声明中看到的,该THub参数没有在任何地方使用,实际上它的存在仅用于依赖项注入目的。

Microsoft.AspNet.SignalR依次包含以下IHubContext声明

// for untyped hub
public interface IHubContext
{
    IHubConnectionContext<dynamic> Clients { get; }
    IGroupManager Groups { get; }
}

// for typed hub
public interface IHubContext<T>
{
    IHubConnectionContext<T> Clients { get; }
    IGroupManager Groups { get; }
}
Run Code Online (Sandbox Code Playgroud)

正如您在本例中所看到的,接口不包含THub参数,并且不需要它,因为ASP.NET MVC没有内置 DI for SignalR. 对于使用类型化客户端,在您的情况下使用就足够了IHubContext<T>。要使用 DI,您必须“手动注入”集线器上下文,正如我在此处描述的那样。