Search code examples
.netsignalrasp.net-core-6.0background-service

How do I add signalR to a background service in different project?


I have a working signal R in my MVC .net core 6.

I have a background service in my MVC project which calls my signalR hub and updates all my pages. I have moved this background service to its own project and now its not working. Is this even possible?

MVC .Net Cor 6 project:

public class ChatHub : Hub
{
    public async Task SendMessage(string user, string message)
    {
        await Clients.All.SendAsync("ReceiveMessage", user, message);
    }
}

background service in a different project:

public class CalculatorConsumer : BackgroundService
{
    private readonly ILogger<CalculatorConsumer> _logger;
    private readonly ISubscriptionClient _subscriptionClient;
    private readonly IHubContext<ChatHub> _hubContext;

    public CalculatorConsumer(
        ILogger<CalculatorConsumer> logger,
        ISubscriptionClient subscriptionClient,
        IHubContext<ChatHub> hubContext)
    {
        _logger = logger;
        _subscriptionClient = subscriptionClient;
        _hubContext = hubContext;
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {

        while (!stoppingToken.IsCancellationRequested)
        {
            _logger.LogInformation("Worker running at: {Time}", DateTime.Now);
            await _hubContext.Clients.All.SendAsync("ReceiveMessage", $"10");
            await Task.Delay(1000, stoppingToken);
        }
    }
}

Solution

  • You could use HubConnectionBuilder to creat a hubconnection to call a remote hub URL. You will not need inject ChatHub in the seperate worker service project. Because you don't have it there, it's in the server.

    In the worker service project, install package Microsoft.AspNetCore.SignalR.Client first .(sometimes you may need to resinstall this package)
    Based on your code, you could modify as following

        public class CalculatorConsumer : BackgroundService
        {
            private readonly ILogger<CalculatorConsumer> _logger;
    
    
            public CalculatorConsumer(ILogger<CalculatorConsumer> logger)
            {
                _logger = logger;
            }
            private List<string> messages = new List<string>(); 
            protected override async Task ExecuteAsync(CancellationToken stoppingToken)
            {
    
                var hubConnection = new HubConnectionBuilder().WithUrl("https://localhost:7218/chatHub").Build();   //change the URL to your server hub URL
                await hubConnection.StartAsync();
    
    
                hubConnection.On<string, string>("ReceiveMessage", (user, message) =>
                {
                    var encodedMsg = $"{user}: {message}";
                    messages = encodedMsg;
                });
    
                while (!stoppingToken.IsCancellationRequested)
                {
                    _logger.LogInformation("Worker running at: {Time}", DateTime.Now);
                    await hubConnection.SendAsync("SendMessage", "workerservice", "10");
                    await Task.Delay(1000, stoppingToken);         
                }
                await hubConnection.DisposeAsync();
            }
        }
    

    Reference:
    Create a Client in .net
    How to add client to blazor