SignalR:无法从 Controller 调用 Hub 方法

SignalR: Unable to call Hub method from Controller

环境:

TL;DR: 将 IHubContext<> 注入 Controller ctor 以便 Action 方法可以向客户端发送消息似乎不起作用。

长版:

我有一个基本的 ASP.NET 核心测试应用程序正在运行,.NET 客户端能够连接和 send/receive 消息。所以我的集线器和客户端似乎工作正常。

我现在正在尝试将控制器添加到 SignalrR Hub 所在的同一个 VS 项目,以便外部参与者可以通过 REST API 端点发送消息。

为此,我尝试使用 DI 将 IHubContext<> 注入我的控制器 ctor,如下所示:

[Route("api/[controller]")]
[ApiController]
public class ValuesController : Controller
{
    private IHubContext<OrgHub> _hubContext;
    public ValuesController(IHubContext<OrgHub> hubContext)
    {
        _hubContext = hubContext;
    }

    //...

}

这似乎成功地注入了正确的 IHubContext,因为当我调试私有成员时,当我连接了 1 个 .NET 客户端时,我看到连接数 = 1。

现在麻烦了: 在操作方法中,我尝试使用 _hubContext 来调用集线器方法...但没有任何反应。调试器通过代码行,我的集线器内没有断点被击中。什么都没有发生。请注意,当 .NET 客户端发送消息(通过 SignalR .NET 客户端)时,我的集线器上的断点确实被命中。它只是我的 Controller/action 方法中的 _hubContext 似乎不起作用。

这是我在操作方法中所做的:

    // GET api/values
    [HttpGet]
    public async Task<ActionResult<IEnumerable<string>>> GetAsync()
    {

        //Try to call "SendMessage" on the hub:
        await _hubContext.Clients.All.SendAsync("SendMessage", "SomeUserName", "SomeMessage");

       //...

        return new string[] { "bla", "bla" };
    }

这里是对应的Hub方法:

 public class OrgHub : Hub
{

    public async Task SendMessage(string user, string message)
    {
        await Clients.All.SendAsync("ReceiveMessage", user, message);
    }

    //...

}

如果有帮助,这里是Startup.cs的编辑版本:

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {

        services.AddSignalR();

        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, IApplicationLifetime applicationLifetime)
    {

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();

        }
        else
        {
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseStaticFiles();


        app.UseSignalR(routes =>
        {
            routes.MapHub<OrgHub>("/rpc");
        });


        app.UseMvc();


    }
}

那么,关于从这里到哪里去有什么想法或建议吗?显然一定有什么我忽略了...

谢谢!

这不是它的工作原理。当您调用 SendAsync 时,该消息将发送给客户端。您不会通过 SendAsync 在集线器上调用方法。什么都没有发生,因为客户实际上收到了一条消息,该消息应该调用监听 "SendMessage" 客户端 的东西,这可能不是您注册客户的东西听。如果目标是点击 "ReceiveMessage" 客户端,那么您应该在控制器中执行 SendAsync("ReceiveMessage", ...)