SignalR集线器在ASP.NET Core中的RabbitMQ订阅处理程序中解析为null [英] SignalR hub resolves to null inside RabbitMQ subscription handler in ASP.NET Core

查看:607
本文介绍了SignalR集线器在ASP.NET Core中的RabbitMQ订阅处理程序中解析为null的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆