In today's guide, you will learn how to implement real-time notifications within Episerver. In this demo, notifications can be updated in real-time either through a 'Content Page Type' being published within Episerver, or, whenever a scheduled task called 'Notification Scheduled Task' runs. When either of these things occurs, the user will instantly be made aware via a notification on the homepage. All this will happen without them having to refresh the page ️‍🔥 ️‍🔥 ️‍🔥 .

Before getting to the code, let's outline the steps required to push messages:

  • Get a list of current notifications
  • Push notifications to all clients when a new message is received
  • Mark a notification as read client-side

As there is a lot of code to involve to set this up, I'm only going to cover the more important aspects. To see the full demo you can clone the project from my GitHub here. Also DO NOT forget to star me ✰⋆🌟✪🔯✨

The real-time messaging works through a library called SignalR. I won't cover how to install SignalR within Episerver in this tutorial, as I've previously gone over it here.

The main class that hangs everything together is the Hub. A hub class is a special SignalR class you need to inherit from. My hub looks like this:

The hub's main purpose is to manage the messaging. How your architecture your own hub will be dependant on your customer requirements. To implement your custom notification logic hook into the methods in this custom hub. In this tutorial, I've followed an architecture based on a Microsoft tutorial. Implementing a singleton class called NotificationCentre to handle the notifications business logic. The NotificationCentre manages Notification objects. In this example, notifications are stored in memory. In reality, this data will likely live in a No-SQL, or SQL database.

A singleton is useful as it stops duplicate actions from being performed. For example, if someone had the scheduled jobs running twice, you could possibly end up with two different notifications for the same action... which I definitely don't want to happen. The code above is pretty self-explanatory, you inherit from Hub and then implement any methods that your custom logic needs. The NotificationCentre code is a little bit more interesting:

On-Line 5, a property to store all the Notification objects are defined. I've added three methods, AddNewNotification, DeleteAllNotifications and GetAllSystemNotifications. This is where my custom business logic lives. The only real SignalR code in this class is BroadcastUpdate. In here I'm passing in my list of Notification objects, into Clients.All.updateNotifications(). Clients is a signalR thing, updateNotifications is the name of an event that I defined.

You can call the methods you define here whatever you want. The important thing to remember is the names have to match up with the names you'll use in the HTML. In my HTML file (which I'll cover below), I create a listener that is attached to updateNotifications. Whenever I call BroadcastUpdate, any clients that have registered with the server will get the notification. The HTML to hook this all up can be seen below:

To help make it easier to visualise what the code looks like on a site, see the screenshot below:

episerver_implementing_a_notifcation_centre_1

The page has two buttons, one to mark a notification as read and the other to delete the message. Clicking on either of these buttons in a browser will trigger a call to the server the notification hub class. The notification hub will then call an instance of the singleton NotificationCentre class and perform the relevant action. As mentioned above, each event will change the notification state. This state is stored in the list of Notification items mentioned above. Eventually BroadcastUpdate() will be called, which will trigger the updateNotification event. This event will trigger a system broadcast so the registered clients will get the notification and can refresh their views accordingly.

All the communication from the HTML to the server is done with the SignalR Javascript library. As you can see in the code above, I'm including jQuery and jquery.signalR.

~/signalr/hubs is a special route within the application that SignalR creates. This route is created in your Startup class when SignalR is registered using this command app.MapSignalR(); call. (See the Installing SignalR tutorial about the Startup class). The Javascript that registers a notifaction listener is shown below:

On Line1, a connection to the hub is established using connection. The name of the hub should be the same as the class name you created earlier (it's the class that inherits from 'Hub'). Remember, the first letter of the method needs to be lowercase, otherwise, the JS will complain that it can't find it!

The code within this Javascript function should update the clients HTML when a broadcast occurs. This code deletes all the current notifications from the notificationBoard div and iterates through each notification pushed from the server and adds it to the HTML using JQuery.

Another thing that is useful to notice is the notificationHub.client call. When you use SignalR you have 'client' and 'server' calls. The client is the way that you set up a listener. Notice how updateNotifications matches the event name I mentioned above (in NotificationCentreBroadcastUpdate() method). You have to use the exact event name otherwise events will not match up. Within server-side code, you write using Clients.All to do the broadcast.

To push a notification to the hub, you use a client JavaScript library call. This is done like this:

This code is a little easier to understand. You're pushing, so you make a server call. The method name on your server call should relate to the method name within your hub class. Again, make sure the method name starts with a lowercase letter, otherwise expect to see a JS exception within the console.

Understanding the differences between these server and client calls confused me when I started with SignalR. When you want to push to the server, you use the 'server' call and the method name of your C# hub code. When you want to create a listener, you need the SignalR method using the client call (in this example, updateNotifications). This name is not translated to a C# class name, this is simply an event name you register with SignalR. You can create as many events as you like and call them whatever you want within SignalR 💥💥💥.

To finish off this tutorial, I'll quickly run through two code examples for triggering a notification from within Episerver. I will show you how to push notifications when a page publish occurs within the CMS and when an Episerver scheduled task completes. If this code is unfamiliar to you, I suggest that you read, Episerver Scheduled Tasks and How to Hook Into The Episerver CMS Events Pipeline.

Scheduled Task To create a notification when an Episerver scheduled tasks finishes, you can use this code:

Page LifeCycle To create a notification when an Episerver page has been saved, you can use this code:


Real-time notifications are pretty easy to implement when you make use of SignalR. SignalR comes with a pretty good server-side and client-side framework that takes the complexities of web sockets away from you. SignalR allows you to focus on your code rather than the messaging. The code in this tutorial might be hard to understand in a single blog post, that is why it is also available to clone from my Github account, here. For more information on SignalR installation, I suggest you look atHow To Install SignalR Within Episerver. Happy Coding 🤘