asp.net-core - SignalR 集线器在 ASP.NET Core 的 RabbitMQ 订阅处理程序中解析为 null
问题描述
我有一个带有 RabbitMQ(通过 EasyNetQ)和 SignalR 的 ASP.NET Core MVC 项目。
接下来,我订阅了一条 RabbitMQ 消息,该消息应通过 SignalR 向客户端发送通知。
但可悲的是,集线器总是解决null
.
一个有趣的观察是,当应用程序仍在启动并且队列中仍有未确认的消息时,服务实际上解决得很好。
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
但我似乎找不到任何有用的例子,所以这是我能想到的最好的例子。
我在 ASP.NET Core 3 preview 5 上,我不知道这是否与我的问题有关。
所以问题是:如何在消息订阅处理程序中获取集线器上下文?
更新
我检查了GetRequiredService 文档InvalidOperationException
,如果服务无法解析,调用实际上应该抛出一个,但它没有。它返回null
,据我所知,这是不可能的(除非默认容器支持注册空值实例)。
解决方案
我已经设法通过实施一个代替这个问题来解决这个问题。IHostedService
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;
}
}
推荐阅读
- java - ExecutorService - 来自调试和在 Eclipse 中运行的不同输出
- ms-access - 如何让 ms-access 保存标签设置?
- django - 如何获取上传文件的绝对路径?- Python + Django
- sql - 如何将一列性别分成男性和女性,然后在 SQL Server 中找到它们的总和?
- rest - Web 应用程序和 ReSTful 应用程序之间的区别?
- php - Instagram 基本显示 API 中的错误:未找到匹配代码或已使用匹配代码
- c# - 如何在 Redis 服务器流式传输上从 c# StackExchange.Redis nuget 包进行阻塞读取
- azure - 在流分析中添加以秒为单位的偏移时间
- python - swig 在 C++ 中运行的结果与在 python 中的不同
- html - 如何在表单中对齐保存按钮右侧