Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SignalR Core Hub Interact With BackgroundService .NET Core

I have read documentation on how to send notifications from a background service to clients through a signalr core hub. How can I receive notifications from clients to the background service?

Background service should only be a singleton.

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);
    }
}

I need to be able to call the SetInterval method from a client. Client is connected through the hub. I don't want another instance of the QueueProcessor to be instantiated either.

like image 521
dom-dev Avatar asked Oct 24 '25 18:10

dom-dev


1 Answers

The way we solved this is adding a third service to the service collection as a singleton.

Here's the full sample PoC: https://github.com/doming-dev/SignalRBackgroundService

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

HelperService raises events that the background service can latch onto.

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);
    }
}

The hub now when clients send a message can call methods on the HelperService which in turn will raise events that the background service is handling.

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);
    }
}
like image 99
dom-dev Avatar answered Oct 28 '25 05:10

dom-dev



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!