These days, all operating systems and browsers have a notification engine. This is a very practical characteristic that enables us to have apps 100% connected and 100% live. With notifications, we can have information about: our other apps, our environments, our users, our fails, etc., when they occur.
SignalR is a library for developers that makes developing real-time functionality very easy with fantastic results.
I have developed a complete .NET solution with a custom notifications system. This solution brings us the possibility to add Notifications to our environments.
A general graphic example:

This project is open source, and is available in my Git Hub Repository.
The solution has … important projects
- Service
SignalR selfhosting project, with the communication service. This app will be installed in a remote server and will be public in a remote address. The others apps and users will be connected to it for sending and receiving messages. - WPFClient
Principal client app connected to communication service. This app will be installed in the user machines, and will show the notifications in real time. - ServiceClientConnect
This project wrappers the connection service functionality two ways: It sends and receives messages. - Domain
Shares the principal types across of solution.
The other projects are client tests.
MLNotifications is open source, and you can download of this article or in GitHub.
Service Project

It is a classical self hosting SignalR service and these are the principals classes:
MessageHub, a class inherit of Hub
- using Microsoft.AspNet.SignalR;
- using MLNotification.Domain;
- using System;
- using System.Threading.Tasks;
- namespace MLNotification.Service
- {
- public class MLMessageHub : Hub
- {
- async public override Task OnConnected()
- {
- // Code for connection to service.
- }
- async public override Task OnDisconnected(bool stopCalled)
- {
- Console.WriteLine("Nueva conexion con Id=" + Context.ConnectionId);
- var message = new NotificationMessage
- {
- Subject = "New service desconnection",
- Body = $"There is a desconnection from the UserId:{Context.ConnectionId}",
- MessageDate = DateTime.Now,
- MessageType = MessageType.Information,
- UriImage = "http://www.tampabay.com/resources/images/dti/rendered/2015/04/wek_plug041615_15029753_8col.jpg"
- };
- await Clients.Caller.ProcessMessage(message);
- await Clients.Others.ProcessMessage(message);
- }
- async public Task SendMessage(NotificationMessage message)
- {
- Console.WriteLine("[" + message.User + "]: " + message.Body);
- await Clients.All.ProcessMessage(message);
- }
- async public Task RegisterUser(UserInfo userInfo)
- {
- // Code for register user
- }
- }
- }
We will show a wrapper class of this class in the project MLNotification.ServiceClientConnect to facilitate the work with the server.
Program.cs
- using Microsoft.Owin.Hosting;
- using System;
- namespace MLNotification.Service
- {
- class Program
- {
- static void Main(string[] args)
- {
- using (WebApp.Start<Startup>("http://localhost:11111"))
- {
- Console.WriteLine("Hub on http://localhost:11111");
- Console.ReadLine();
- }
- }
- }
- }
Startup.cs
- using Microsoft.Owin.Cors;
- using Owin;
- namespace MLNotification.Service
- {
- public class Startup
- {
- public static void Configuration(IAppBuilder app)
- {
- app.UseCors(CorsOptions.AllowAll);
- app.MapSignalR();
- }
- }
- }
Client
Is a WPF application in MVVM, and is connected to service all time. It has two principal parts

This is the Notify Icon + Tooltip.
It’s a notify Icon, showing the popup notification message (if the notification grid is closed, but this behavior can be set up) and opens the surface grid notifications. It has a context menu with two options, the first is a shortcut to configuration and the second closes the app. For this part, I have used the fantastic library WPF NotifyIcon by the developer Philipp Summi, I recommend it very much.
The second part is the surface grid notifications,

The surface grid notifications, is a bag for showing the notification messages. The notification messages can be closed one to one or clean all. In the button of control is an access to configuration that we will cover after.
Notification Types
There are 8 notifications types, these are divided in 2 groups: less important (simple) and important messages (urgent). Inside each group there are 4 types: Information, warning, error and Very Important.


MLNotification.WPFClient Code Project

The WPF project contains 4 groups. The image speaks for itself. For more details view the classes in the download project.
Settings

In the Settings windows, we will configure 2 principal application parts,
- Service
- Service Address .- Is the http address where we will expose the service.
- Service Address .- Is the http address where we will expose the service.
- Balloon Messages
- Visibility Time (Seconds) .- This option sets the time balloon messages will be visible.
- Show Balloon with notifications open .- If this property is activated, the balloons messages always will be displayed, in other case, the balloons messages only show with the Notifications panel closed.
The information settings will be saved in the user Isolated Storage, and will reconnect the server for each one saved.
If you misconfigure the address setting, the panel settings shows the connection error

NotificationMessage Class
NotificationMessage class is a very important class in the solution. This class travels across service and the clients and contains the message information.
- using System;
- using System.ComponentModel.DataAnnotations;
- namespace MLNotification.Domain
- {
- [Serializable]
- public class NotificationMessage : INotificationMessage
- {
- [Required]
- [MaxLength(100)]
- public string Subject { get; set; }
- [Required]
- [MaxLength(2000)]
- public string Body { get; set; }
- public MessageType MessageType { get; set; }
- [MaxLength(50)]
- public string Group { get; set; }
- [MaxLength(50)]
- public string User { get; set; }
- [MaxLength(50)]
- public string Server { get; set; }
- public DateTime MessageDate { get; set; }
- public string UriImage { get; set; }
- }
- }
- namespace MLNotification.Domain
- {
- public enum MessageType
- {
- Information,
- Warnnig,
- Error,
- VeryImportant,
- Information_urgent,
- Warnnig_urgent,
- Error_urgent,
- VeryImportant_urgent
- }
- }
Your properties names explain themselves.
MessageType covers all cases showed previously.
MLNotification.ServiceClientConnect
This is a server connection wrapper. ServiceClientConnect tries to facilitate the communication between the server and the client, removing the dynamic approach for a strongly typed one.
MLMessageHubConect is its principal class.




jonathan dechaseauxPosted Jan 24, 2023, 10:37 AM
Hi, thanks for the article, really useful, i tried to use it in the hospital where I work. It works fine, but I don't know how to add an auto-reconnect feature. I would like the wpf client app to auto reconnect when it detects a disconnected state. Can you help me ? Thanks in advance ;)