【问题标题】:SignalR: Unable to call Hub method from ControllerSignalR:无法从控制器调用集线器方法
【发布时间】:2018-12-18 13:50:41
【问题描述】:

环境:

  • 最新更新的 Visual Studio 2017 社区
  • 目标框架:.NET Core 2.1(最新版本)
  • SignalR 核心
  • 在 Windows 10 的 IIS Express 上运行(开发环境)

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

加长版:

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

我现在正尝试将控制器添加到 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();


    }
}

那么,关于从这里去哪里有什么想法或建议吗?很显然,我忽略了某些东西......

谢谢!

【问题讨论】:

    标签: c# asp.net-core signalr signalr-hub asp.net-mvc-controller


    【解决方案1】:

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

    【讨论】:

    • 谢谢。有没有办法从控制器调用集线器上的方法?我有一些基本逻辑,我不想在控制器中重复。我想我可以把它全部提取到一个类库中。然而,就我自己的知识而言,有什么方法可以调用集线器方法并像我试图做的那样进行这项工作?
    • 没有。那不是他们的目的。您的集线器上的方法供 clients 调用。以与在客户端上调用 subscribe 相同的方式来考虑它们。这些是服务器的钩子,就像集线器上的方法是客户端的钩子一样。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-27
    • 2023-03-05
    • 1970-01-01
    相关资源
    最近更新 更多