SignalR and Worker Service in .NET Core

Levent Ozturk
4 min readJul 26, 2023

--

Hello again,

In today’s article, I will try to explain how and for what purposes we can use Microsoft’s SignalR library with a worker service.

Before starting, you can access my Medium article about worker service here: Click!

Let’s start with our definitions.

What is the SignalR?

If I have to explain it very briefly: SignalR is a library developed by Microsoft and used to build real-time web applications.

The Ecosystem

Real-time applications, also called “Real-Time Web” or “WebSockets”, refer to applications that need instant communication between server and client. For example, SignalR can be used in scenarios such as an online chat application, push notifications, live data updates.

SignalR is a server-side library that can communicate with clients from web browsers, mobile devices or other platforms. SignalR automatically selects the most appropriate communication mechanism to ensure compatibility between different browsers and devices.

What is the worker service?

I gave the link to my detailed article on this subject at the beginning of the article. But still, to mention it briefly: Worker Service is a framework for creating applications that run continuously in the background and perform long-running operations. These operations can be tasks, database operations, file operations or other processes that are usually run from time to time.

We have defined our definitions!

How can we combine these two?

By using SignalR and Worker Service together, it is possible to create applications that need real-time data processing and updates. For example, when a Worker Service running in the background on a system regularly performs a specific task, the results of this task can be instantly sent to web browsers or other clients with SignalR. Thus, users can follow the real-time status of the system or receive push notifications.

Our scenario is a stock price tracking application: A Worker Service running in the background will periodically update stock prices and store them in a database. Using SignalR, these updated stock prices are transmitted to web browsers in real time and users can instantly see the current stock prices.

First of all, we create an ASP.NET Core project. Then we can create a class-library for SignalR, add this nuget package: ”Microsoft.AspNetCore.SignalR.Core” and write hub codes for SignalR. Like this:

using Microsoft.AspNetCore.SignalR;

namespace SignalR
{
public class StockHub : Hub
{
public async Task SendStockPrice(string stockName, decimal price)
{
await Clients.All.SendAsync("ReceiveStockPrice",stockName, price);
}
}
}

Yes, basicyl we take just “stockName” and “stockPrice”.

Then, we create a worker service, add dependency for our hub.

using Microsoft.AspNetCore.SignalR;
using SignalR;

namespace BasicWorkerService
{
public class Worker : BackgroundService
{
private readonly ILogger<Worker> _logger;
private readonly IHubContext<StockHub> _stockHub;
private const string stockName = "Basic Stock Name";
private const decimal stockPrice = 100;

public Worker(ILogger<Worker> logger, IHubContext<StockHub> stockHub)
{
_logger = logger;
_stockHub = stockHub;
}

protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
_logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);

//do some stock works

Random rnd = new Random();
decimal stockRaise = rnd.Next(1, 100);

await _stockHub.Clients.All.SendAsync("ReceiveStockPrice", stockName, stockPrice+ stockRaise);
await Task.Delay(4000, stoppingToken);
}
}
}
}

Here I wanted to increase the “stockPrice” value randomly to see the changes on the screen more easily.

After all that. We can create our web application. It will be very, very simple view. We will only show “stockName” and “stockPrice” values on the index page.

But before that, we need to add the hub and worker service to our web application. For this:

builder.Services.AddSignalR();
builder.Services.AddHostedService<Worker>();
app.MapHub<StockHub>("/hubs/stock");

This is our hub’s route: app.MapHub<StockHub>(“/hubs/stock”);

And now, we can manage our view page.

Index.cshtml

<script src="https://cdnjs.cloudflare.com/ajax/libs/microsoft-signalr/6.0.1/signalr.js"></script>
<script>
const connection = new signalR.HubConnectionBuilder().withUrl("/hubs/stock").configureLogging(signalR.LogLevel.Information).build();

connection.on("ReceiveStockPrice", (stockName, stockPrice) => {
const li = document.createElement("li");
li.textContent = `${stockName}: ${stockPrice}`;
document.getElementById("messageList").appendChild(li);
});

connection.start()
.then(() => {
console.log("SignalR connection started successfully.");
})
.catch((err) => {
console.error("Error starting SignalR connection: " + err);
});

</script>
<ul id="messageList"></ul>

First, the SignalR connection is configured and created.

After that, added a listener to the “ReceiveStockPrice” event from the server. So, when the server triggers this event, the code block here runs.

Finally, started the SignalR conneciton.

We can see how we get the data

In this very simple project, I have tried to explain the SignalR and worker service combination. It is up to your imagination to configure this duo according to your needs. You can find the code of this project on my GitHub account.

Thank you very much for reading.
Happy coding!

--

--