SignalR集线器在ASP.NET Core中的RabbitMQ订阅处理程序中解析为null [英] SignalR hub resolves to null inside RabbitMQ subscription handler in ASP.NET Core
问题描述
我有一个使用RabbitMQ(通过EasyNetQ)和SignalR的ASP.NET Core MVC项目.
I have an ASP.NET Core MVC project with RabbitMQ (by means of EasyNetQ) and SignalR.
接下来,我对RabbitMQ消息进行了订阅,该消息应通过SignalR向客户端发送通知.
Next, I have a subscription on a RabbitMQ message that should send a notification to the client via SignalR.
但是可悲的是,集线器始终解析为<c0>.
But sadly, the hub always resolves to null
.
一个有趣的发现是,当应用程序仍在启动并且队列中仍然存在未确认的消息时,该服务实际上可以很好地解决.
An interesting observation is that when the application is still starting and there are still unacknowledged messages in the queue, the service actually resolves just fine.
public void ConfigureServices(IServiceCollection services)
{
services.AddSignalR();
services.RegisterEasyNetQ("host=localhost;virtualHost=/");
}
public void Configure(IApplicationBuilder app)
{
app.UseSignalR(route =>
{
route.MapHub<MyHub>("/mypath");
});
app.Use(async (context, next) =>
{
var bus = context.RequestServices.GetRequiredService<IBus>();
bus.SubscribeAsync<MyMessage>("MySubscription", async message =>
{
var hubContext = context.RequestServices
.GetRequiredService<IHubContext<MyHub>>();
// hubContext is null
await hubContext.Clients.All.SendAsync("MyNotification");
});
await next.Invoke();
});
}
我怀疑在app.Use
中注册订阅时可能做错了,但是我似乎找不到任何有用的示例,所以这是我能想到的最好的示例.
I suspect that perhaps I'm doing something wrong with regards to registering the subscription inside an app.Use
but I can't seem to find any useful examples so this was the best I could figure.
我正在使用ASP.NET Core 3预览5,我不知道这是否与我的问题有关.
I'm on ASP.NET Core 3 preview 5, I don't know if that has anything to do with my problem.
所以问题是:如何在消息订阅处理程序中获取中心上下文?
So the question is: how do I get the hub context inside the message subscription handler?
更新
我已经检查了 GetRequiredService文档,如果无法解析该服务,但调用无法解决,则该调用实际上应该抛出一个InvalidOperationException
.它返回null
,据我所知,这应该是不可能的(除非默认容器支持空值实例的注册).
I've checked the GetRequiredService docs and the call should actuall throw an InvalidOperationException
if the service couldn't be resolved, but it doesn't. It returns null
, which as far as I can tell, shouldn't be possible (unless the default container supports registration of null-valued instances).
推荐答案
I've managed to solve the issue with help from this issue by implementing an IHostedService
instead.
public void ConfigureServices(IServiceCollection services)
{
services.AddSignalR();
services.RegisterEasyNetQ("host=localhost;virtualHost=/");
services.AddHostedService<MyHostedService>();
}
public void Configure(IApplicationBuilder app)
{
app.UseSignalR(route =>
{
route.MapHub<MyHub>("/mypath");
});
}
public class MyHostedService : BackgroundService
{
private readonly IServiceScopeFactory _serviceScopeFactory;
public ServiceBusHostedService(IServiceScopeFactory serviceScopeFactory)
{
_serviceScopeFactory = serviceScopeFactory;
}
protected override Task ExecuteAsync(CancellationToken stoppingToken)
{
var scope = _serviceScopeFactory.CreateScope();
var bus = scope.ServiceProvider.GetRequiredService<IBus>();
bus.SubscribeAsync<MyMessage>("MySubscription", async message =>
{
var hubContext = scope.ServiceProvider.GetRequiredService<IHubContext<MyHub>>();
await hubContext.Clients
.All
.SendAsync("MyNotification", cancellationToken: stoppingToken);
});
return Task.CompletedTask;
}
}
这篇关于SignalR集线器在ASP.NET Core中的RabbitMQ订阅处理程序中解析为null的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!