gpt4 book ai didi

asp.net-core - 如何在类中注入(inject)强类型 signalR 集线器 [ASP CORE 2.2]

转载 作者:行者123 更新时间:2023-12-03 22:01:43 27 4
gpt4 key购买 nike

我想在服务中注入(inject)我的强类型集线器,但我不喜欢 Microsoft 显示的示例中的某些内容 - https://docs.microsoft.com/en-us/aspnet/core/signalr/hubcontext?view=aspnetcore-2.2 (注入(inject)一个强类型的 HubContext)

public class ChatController : Controller
{
public IHubContext<ChatHub, IChatClient> _strongChatHubContext { get; }

public ChatController(IHubContext<ChatHub, IChatClient> chatHubContext)
{
_strongChatHubContext = chatHubContext;
}

public async Task SendMessage(string message)
{
await _strongChatHubContext.Clients.All.ReceiveMessage(message);
}
}

在此示例中 ChatHub耦合到 ChatController .

所以我想注入(inject)集线器本身
使用通用接口(interface)参数定义,并且不会在我的服务中定义它的具体实现。
这是示例代码
public interface IReportProcessingClient
{
Task SendReportInfo(ReportProgressModel report);
}
public class ReportProcessingHub : Hub<IReportProcessingClient>
{
public async Task SendMessage(ReportProgressModel report)
{
await Clients.All.SendReportInfo(report);
}
}

 public class ReportInfoHostedService : IHostedService, IDisposable
{
private readonly Hub<IReportProcessingClient> _hub;
private readonly IReportGenerationProgressService _reportService;

public ReportInfoHostedService(Hub<IReportProcessingClient> hub, IReportGenerationProgressService reportService)
{
_hub = hub;
_reportService = reportService;
}

public Task StartAsync(CancellationToken cancellationToken)
{
_reportService.SubscribeForChange(async x =>
{
await _hub.Clients.All.SendReportInfo(x);
});

return Task.CompletedTask;
}

public Task StopAsync(CancellationToken cancellationToken)
{
return Task.CompletedTask;
}

public void Dispose()
{
}
}

这种方法显然需要在 Startup.cs 中额外注册集线器,因为 Microsoft 提供的上下文 api 不会调用它。
services.AddSingleton<Hub<IReportProcessingClient>, ReportProcessingHub>();
app.UseSignalR(route => {
route.MapHub<ReportProcessingHub>("/reportProcessingHub");
});

在集线器尝试向客户端发送消息之前,一切都已完成并正常工作。然后我得到了异常
_hub.Clients.All threw an exception of System.NullReferenceException: 'Object reference not set to an instance of an object.'

所以总结一下:

1. 这是注入(inject)强类型集线器的正确方法吗?我做错了什么(例如,集线器在服务中的错误注册,app.UseSingleR 的错误使用)?

2. 如果不是,正确的方法是什么?

笔记:
我知道注入(inject) IHubContext<Hub<IReportProcessingClient>> 有很多更简单的方法,但这对我来说不是解决方案,因为我必须调用作为 string 传递的集线器方法名称范围。

最佳答案

I want to ... and no concrete implementation of it will be defined in my service


  • 如果您不想公开具体的集线器实现,您至少应该公开 基类 接口(interface) .但是,由于集线器应该继承自 Hub类,我们不能在这里使用接口(interface)。因此,让我们创建一个公共(public)基础中心 ReportProcessingHubBase以及内部混凝土ReportProcessingHub :

    public abstract class ReportProcessingHubBase : Hub<IReportProcessingClient>
    {
    public abstract Task SendMessage(ReportProgressModel report);
    }

    // the concrete hub will NOT be exposed
    internal class ReportProcessingHub : ReportProcessingHubBase
    {
    public override async Task SendMessage(ReportProgressModel report)
    {
    await Clients.All.SendReportInfo(report);
    }
    }
  • 确保您已经注册了两个相关的服务:

    services.AddScoped<ReportProcessingHubBase, ReportProcessingHub>();
    services.AddHostedService<ReportInfoHostedService>();
  • 确保您正在映射 基地中心 ( 最重要的!):

     endpoints.MapHub<ReportProcessingHubBase>("/report");
  • 最后,您可以通过注入(inject) IHubContext<ReportProcessingHubBase,IReportProcessingClient> 获得基础集线器:
    public class ReportInfoHostedService : IHostedService, IDisposable
    {
    private readonly IHubContext<ReportProcessingHubBase,IReportProcessingClient> _hub;

    public ReportInfoHostedService(IHubContext<ReportProcessingHubBase,IReportProcessingClient> hub)
    {
    _hub = hub;
    }

    ...
    }

    现在,您可以以强类型的方式调用 hub 方法。
  • 关于asp.net-core - 如何在类中注入(inject)强类型 signalR 集线器 [ASP CORE 2.2],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59360487/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com