ASP.NET Core 8.0 - SignalR Online User Count

This article will describe the implementation of Microsoft .AspNetCore .SignalR to count online users. You should review the earlier articles of the Cookies And Claims Project series. Registered users can download the ASP.NET Core 8.0 - Cookies And Claims Project for free.

Cookies And Claims Project and Article Series

Free project download for registered users!

I developed the Cookies And Claims Project (CACP) to demonstrate a simple cookie authentication scheme and claim-based authorization with a clear and modifiable design. The CACP is developed with Visual Studio 2022 and the MS Long Term Support (LTS) version .NET 8.0 framework. All Errors, Warnings, and Messages from Code Analysis have been mitigated. The CACP implements utilities like an AES Cipher, Password Hasher, native JavaScript client form validation, password requirements UI, Bootstrap Native message modal generator, loading/spinner generator, SignalR online user count, and an automatic idle logout for users with administration permissions.

The CACP implements a feature based on a couple of examples I found which count online users with SignalR. The feature requires a SignalR Hub on the server, the JavaScript SignalR client library, JavaScript SignalR client code, and a little UI to display the current online user count. First, SignalR is added to the Services container.

Program.cs:
builder.Services.AddSignalR();

The CACP implements a SignalR Hub named OnlineCountHub. The Hub is mapped to the "/onlinecount" URL with the HTTP request pipeline configuration.

app.MapHub<OnlineCountHub>("/onlinecount");
Hubs > OnlineCountHub.cs:
public class OnlineCountHub : Hub
{
    private static int Count = 0;
    public override async Task OnConnectedAsync()
    {
        Count++;
        await base.OnConnectedAsync().ConfigureAwait(false);
        await Clients.All.SendAsync("updateCount", Count).ConfigureAwait(false);
    }
    public override async Task OnDisconnectedAsync(Exception? exception)
    {
        Count--;
        await base.OnDisconnectedAsync(exception).ConfigureAwait(false);
        await Clients.All.SendAsync("updateCount", Count).ConfigureAwait(false);
    }
}

The CACP implements libman.json and installs the signalr.js client-side library. See Use LibMan with ASP.NET Core in Visual Studio.

libman.json:
{
  "destination": "wwwroot/lib/signalr/dist/browser/",
  "files": [
    "signalr.js",
    "signalr.min.js"
  ],
  "library": "microsoft-signalr@8.0.7"
}

The SignalR client code builds a connection to the "/onlinecount" endpoint.

wwwroot > js > site.js:
// Depends on signalr.js and OnlineCountHub.cs
let onlineCount = document.querySelector('span.online-count');
if (typeof (signalR) !== "undefined") {
    let countConnection = new signalR.HubConnectionBuilder()
        .withUrl('/onlinecount').build();
    let updateCountCallback = function (message) {
        if (!message) return;
        if (onlineCount) onlineCount.innerText = message;
    };
    function onConnectionError(error) {
        if (error && error.message) console.error(error.message);
    }
    countConnection.on('updateCount', updateCountCallback);
    countConnection.onclose(onConnectionError);
    countConnection.start()
        .then(function () {
            console.log('OnlineCount Connected');
        })
        .catch(function (error) {
            if (showMessageModal)
                showMessageModal(error.message, 'alert-danger');
            console.error(error.message);
        });
}

The CACP loads the SignalR client library and site.js with the layout.

Pages > Shared > _Layout.cshtml:
<environment include="Development">
    <script src="~/lib/bootstrap/dist/js/bootstrap-native.js"></script>
    <script src="~/lib/signalr/dist/browser/signalr.js"></script>
    <script src="~/js/dynamic-modals.js"></script>
    <script src="~/js/site.js" asp-append-version="true"></script>
</environment>
<environment exclude="Development">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap.native/5.0.13/bootstrap-native.min.js"
            asp-fallback-src="~/lib/bootstrap/dist/js/bootstrap-native.min.js" asp-fallback-test="window.BSN"
            integrity="sha512-GEfg7GTt1iOZ2KqRiQ9HY7lvcvRpD6J9RhCIq99VQBLWvB7hgDJ7oZu9dvhWwqgFHrXh4x4NcLJc1dUsr7dlPw=="
            crossorigin="anonymous" referrerpolicy="no-referrer">
    </script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/microsoft-signalr/8.0.7/signalr.min.js"
            asp-fallback-src="~/lib/signalr/dist/browser/signalr.min.js" asp-fallback-test="window.signalR"
            integrity="sha512-7SRCYIJtR6F8ocwW7UxW6wGKqbSyqREDbfCORCbGLatU0iugBLwyOXpzhkPyHIFdBO0K2VCu57fvP2Twgx1o2A=="
            crossorigin="anonymous" referrerpolicy="no-referrer">
    </script>
    <script src="~/js/dynamic-modals.min.js"></script>
    <script src="~/js/site.min.js" asp-append-version="true"></script>
</environment>

The CACP implements a span with a online-count class on the Members and Admin pages which displays the current online user count.

Pages > Members > Index.cshtml:
<div class="row border-bottom mb-1">
    <div class="col-12">
        <h5 class="d-inline-flex me-2">Online Count:<span class="online-count px-2"></span></h5>
        <h5 class="d-inline-flex">Browse any page of this site with a second tab or browser to increment the online count.</h5>
    </div>
</div>

The Members and Admin page images are when 3 tabs are open.

Members Page.
Admin Page.
Ken Haggerty
Created 08/29/24
Updated 10/24/24 20:53 GMT

Log In or Reset Quota to read more.

Article Tags:

Analytics VS 2022
Successfully completed. Thank you for contributing.
Processing...
Something went wrong. Please try again.
Contribute to enjoy content without advertisments.
You can contribute without registering.

Comments(0)

Loading...
Loading...

Not accepting new comments.

Submit your comment. Comments are moderated.

User Image.
DisplayedName - Member Since ?