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
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,
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 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:
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.
~/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
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!
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
BroadcastUpdate() 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
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
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 🤘