SignalR:无法从 Controller 调用 Hub 方法
SignalR: Unable to call Hub method from Controller
环境:
- Visual Studio 2017 社区最新更新
- 目标框架:.NET Core 2.1(最新版本)
- SignalR 核心
- 运行 在 Windows 10(开发环境)
上的 IIS Express 上
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", ...)
。
环境:
- Visual Studio 2017 社区最新更新
- 目标框架:.NET Core 2.1(最新版本)
- SignalR 核心
- 运行 在 Windows 10(开发环境) 上的 IIS Express 上
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", ...)
。