SignalR Core Hub Взаимодействует с BackgroundService .NET Core - PullRequest
0 голосов
/ 18 апреля 2019

Я прочитал документацию о том, как отправлять уведомления из фоновой службы клиентам через основной концентратор сигналов. Как я могу получать уведомления от клиентов в фоновом режиме?

Фоновая служба должна быть только одноразовой.

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddHostedService<QueueProcessor>();
        services.AddSignalR();
    }

    public void Configure(IApplicationBuilder app)
    {
        app.UseSignalR(routes =>
        {
            routes.MapHub<AutoCommitHub>("/autocommithub");
        });
    }
}



public class QueueProcessor : BackgroundService
{
    private int interval;

    public QueueProcessor(IHubContext<AutoCommitHub> hubContext)
    {
        this.hub = hubContext;
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
            await BeginProcessingOrders();
            Thread.Sleep(interval);
        }
    }

    internal async Task BroadcastProcessStarted(string orderNumber)
    {
        await hub.Clients.All.SendAsync("ReceiveOrderStarted", 
                                                 orderNumber);
    }

    internal void SetInterval(int interval)
    {
        this.interval = interval;
    }
}



public class AutoCommitHub : Hub
{
    private readonly QueueProcessor queueProcessor;
    public AutoCommitHub(QueueProcessor _processor)
    {
        queueProcessor = _processor;
    }

    public void SetIntervalSpeed(int interval)
    {
        queueProcessor.SetInterval(interval);
    }
}

Мне нужно иметь возможность вызывать метод SetInterval от клиента. Клиент подключен через хаб. Я не хочу, чтобы создавался другой экземпляр QueueProcessor.

Ответы [ 2 ]

0 голосов
/ 23 апреля 2019

Вам не нужен еще один экземпляр QueueProcessor. Клиент может легко вызвать SetIntervalSpeed ​​из своего кода. Документация с примером.

var connection = new signalR.HubConnectionBuilder().withUrl("/autocommithub").build();
connection.invoke("SetIntervalSpeed", interval)

SignalR предоставляет API для создания сервер-клиент RFC .

0 голосов
/ 19 апреля 2019

Способ, которым мы решили это, - добавление третьего сервиса в коллекцию сервисов как одиночного.

Вот полный пример PoC: https://github.com/doming-dev/SignalRBackgroundService

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddHostedService<QueueProcessor>();
        services.AddSingleton<HelperService>();
        services.AddSignalR();
    }
}

HelperService вызывает события, на которые может зацепиться фоновая служба.

public class HelperService : IHelperService
{
    public event Action OnConnectedClient = delegate { };
    public event Action<int> SpeedChangeRequested = delegate { };
    public void OnConnected()
    {
        OnConnectedClient();
    }

    public void SetSpeed(int interval)
    {
        SpeedChangeRequested(interval);
    }
}

Концентратор теперь, когда клиенты отправляют сообщение, может вызывать методы на HelperService, которые, в свою очередь, будут вызывать события, которые обрабатывает фоновая служба.

public class MyHub : Hub
{
    private readonly IHelperService helperService;

    public MyHub(IHelperService service)
    {
        helperService = service;
    }

    public override async Task OnConnectedAsync()
    {
        helperService.OnConnected();
        await base.OnConnectedAsync();
    }

    public void SetSpeed(int interval)
    {
        helperService.SetSpeed(interval);
    }
}
...