SignalR:无法从Controller调用Hub方法

Environment:

  • Visual Studio 2017社区,提供最新更新

  • 目标框架:.NET Core 2.1(最新版本)

  • SignalR核心

  • 在Windows 10上的IIS Express上运行(开发环境)

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

Long version:

我有一个基本的ASP.NET核心测试应用程序,.NET客户端能够连接和发送/接收消息 . 所以我的Hub和客户似乎工作正常 .

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

为此,我尝试使用DI将IHubContext <>注入 ctor of my controller ,如下所示:

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

    //...

}

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

Now the trouble: 在一个动作方法中我尝试使用_hubContext来调用一个hub方法......但没有任何反应 . 调试器通过代码行传递,我的Hub中没有断点 . 什么都没发生 . 请注意,当.NET客户端发送消息时(通过SignalR .NET客户端),我的Hub上的断点确实会受到影响 . 它只是我的控制器/动作方法中的_hubContext似乎不起作用 .

以下是我在_1307407中所做的事情:

// 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 method

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();


    }
}

那么,关于从哪里去的任何想法或建议?显然必须有一些我忽略的东西......

谢谢!

回答(1)

2 years ago

这不是这个工作原理 . 当您拨打 SendAsync 时,该消息将发送给客户端 . 您不通过 SendAsync 调用集线器上的方法 . 没有任何事情发生,因为客户端实际上会收到一条消息,该消息应该调用监听"SendMessage"客户端的内容,这可能不是您注册客户端要监听的内容 . 如果目标是命中"ReceiveMessage"客户端,那么你应该在控制器中执行 SendAsync("ReceiveMessage", ...) .