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.
- ASP.NET Core 8.0 - Cookies And Claims
- ASP.NET Core 8.0 - Cookie Authentication
- ASP.NET Core 8.0 - Remember Me Or Not
- ASP.NET Core 8.0 - Authorized Access
- ASP.NET Core 8.0 - Administrator Claim
- ASP.NET Core 8.0 - Admin Idle Logout
- ASP.NET Core 8.0 - Cookie Consent
- ASP.NET Core 8.0 - SignalR Online User Count
- ASP.NET Core 8.0 - AES Cipher
- ASP.NET Core 8.0 - Password Hasher
- ASP.NET Core 8.0 - Message Generator
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.
Comments(0)