【问题标题】:How to access IHubContext in net core web api from singleton class如何从单例类访问 net core web api 中的 IHubContext
【发布时间】:2018-11-27 08:50:02
【问题描述】:

ASP.NET CORE 2.1 WEB API

我有一个单例类,它是一个在 Startup.cs 中启动的 tcpip 客户端 (TcpIpService),此时 API 需要一直运行。我无法弄清楚如何从这个单例访问 IHubContext 以便能够通过 SignalR 将 tcp 数据发送到 Web 前端。

我曾尝试通过 sigleton 类中的静态 Action 属性触发此操作,但是当在 Hub 中触发此操作时,Hub 已被释放,我得到 (System.ObjectDisposedException: 'Cannot access a disposed object.')

在单例类中

public static Action<string> DataArrived { get; set; }

以及何时在中心

TcpIpService.DataArrived = new Action<string>(MessageFromPlcReceived);

我知道这可以注入到控制器或服务中,但我需要它才能从其他地方访问它。

我知道 GlobalHost 在新 SignalR 中不可用,并且 IHubContext 很容易注入,但这对于在 Startup.cs 中单独实例化的单例类不起作用(至少到目前为止)

任何想法如何做到这一点?

在通过 SignalR GitHub 存储库后,我发现了一种丑陋的方法。我可以在我的 Startup.cs, Configure 方法中做到这一点:

TcpIpService.HubContext = app.ApplicationServices.GetRequiredService<IHubContext<VcHub>>();

这只是创建旧 GlobalHost 之前所做的事情。如此丑陋,我找不到更好的解决方案......到目前为止。有更好的方法吗?

【问题讨论】:

  • 我对 SignalR 没有太多经验,但是你的单例线程安全吗?当同时执行两个或多个请求时它会起作用吗?
  • tcp 客户端(单例)经过测试已被遗忘,所以我并不担心我的单例。我担心的是它如何与 SignaR 对话......
  • 一些搜索给了我这个:GlobalHost.ConnectionManager.GetHubContext&lt;MyHub&gt;();这不是你要找的吗?
  • @vasily.sib 查看更新后的问题。 GlobalHost 在旧 SignalR 中工作,但在新 SignalR 中不再可用。

标签: c# asp.net-core signalr


【解决方案1】:

我没有找到解决这个问题的正确方法,所以我将 TcpService 重写为 IHostedService,然后我可以在 Startup.xml 中注册它。 cs 并将 IHubContext 注入服务并从所需类访问上下文。

...
using Microsoft.Extensions.Hosting;
...

public class HostedTcpIpService : IHostedService, IDisposable
{
    #region Declaration(s)

    private readonly ILogger<HostedTcpIpService> logger;
    private readonly IHubContext<VcHub> hubContext;

    #endregion

    #region Constructor

    public HostedTcpIpService(
        ILogger<HostedTcpIpService> logger,
        IHubContext<VcHub> hubContext)
    {
        this.logger = logger;
        this.hubContext = hubContext;
    } 

    #endregion

    #region IDisposable

    public void Dispose()
    {
        // disposing
    } 

    #endregion

    #region IHostedService

    public Task StartAsync(CancellationToken cancellationToken)
    {
        // Start Tcp connection
    }

    public Task StopAsync(CancellationToken cancellationToken)
    {
        // Stop Tcp connection
    }

    #endregion

    private void OnTcpMessageReceived(string tcpMessage) 
    {
        // injected hubContext ...
        // broadcast to signalR clients
        this.hubContext.Clients.All.SendAsync("broadcastMessage", tcpMessage);
    }
}

在 Startup.cs 中

public void ConfigureServices(IServiceCollection services) 
{ 
    ...

    services.AddSingleton<Microsoft.Extensions.Hosting.IHostedService, HostedTcpIpService>();

    ...
}

【讨论】:

    猜你喜欢
    • 2020-12-13
    • 2021-06-09
    • 1970-01-01
    • 1970-01-01
    • 2020-07-01
    • 2018-09-04
    • 1970-01-01
    • 1970-01-01
    • 2019-04-22
    相关资源
    最近更新 更多