Как получить доступ к IHubContext в сетевом интерфейсе ядра сети из класса Singleton - PullRequest
0 голосов
/ 27 ноября 2018

ASP.NET CORE 2.1 WEB API

У меня есть одноэлементный класс, который является tcpip-клиентом (TcpIpSerrvice), запущенный в Startup.cs, когда API выполняет и должна работать все время.Я не могу понять, как получить доступ к IHubContext из этого синглтона, чтобы иметь возможность отправлять tcp-данные в веб-интерфейс через SignalR.

Я пытался вызвать это через статическое свойство Action в классе сиглета, но когда этозапускается в Hub, Hub уже удален, и я получаю (System.ObjectDisposedException: «Не удается получить доступ к удаленному объекту.»)

в одноэлементном классе

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.Как бы ужасно это ни было, я не могу найти лучшего решения ... пока.Есть ли лучший способ сделать это?

1 Ответ

0 голосов
/ 07 марта 2019

Я не нашел подходящего способа обойти это, поэтому я переписал TcpService как IHostedService и затем мне удалось зарегистрировать это в Startup.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);
    }
}

In Startup.cs

public void ConfigureServices(IServiceCollection services) 
{ 
    ...

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

    ...
}
...