Everyone reading this should understand the concepts of a notification area on a website, we’ve all been using website’s long enough! A notification is a message you can display to the user, usually as an icon in a notification area, usually in the header of your website. Recently, a client wanted to add a notification area to the header of their website. Obviously, there are several ways of doing this and in today’s post, I’m going to cover the three main contenders.
In this scenario, we have a header where all the standard stuff, like logo, navigation, search bar etc.. are processed and rendered server side. As this data won’t change very often it means we can add a long expiry data on it to help make the website more performant. The user profile and notification area in the header will then be populated via AJAX. In this vein the size of the data packets required for each page request is kept to the minimum it can be.
This post is the first of a two-parter, in this first post, I’m going to evaluate the different ways of architecting the solution. In the second post, I’ll walk you through my solution by talking you through a sample project that provides the basic outline.
Option One: Wait for the user to refresh the page. In this scenario we do nothing. If a new notification needs to be displayed on the page, we wait until the user refreshes the page and get a new AJAX payload. This option is definitely the easiest as it doesn’t involve any additional code. If the user is using your website a lot, then the chances of them getting the new notification quickly are pretty high. If your website visitors don’t refresh your pages often, then they might not get your notification for several hours.
Options Three: Observer/Subscriber Pattern: Using an observer pattern, you get all clients to register with your server. When a new notification comes in you send a broadcast signal to all of your clients telling them that your data source has been updated. This approach is pretty efficient because you don’t have the downsides of long polling and the wasted resourcing. Clients only run code when a broadcast has been made, instead of polling every 10 seconds. It also means the user doesn’t have to wait to refresh the page.
The main problem when you start to think about observer/subscriber patterns is how will you deal with the messaging of data. One of the more popular ways of dealing with this real-time messaging (at the time of writing) seems to be web sockets. Web Sockets do have some very big limitations so I wouldn’t just jump right out and start using them straightaway without considering a few things first. Web socket doesn’t seem to play that nicely within load balanced environments, or HTTP2, which are two main features most enterprise level organizations will want to use.
This article, https://samsaffron.com/archive/2015/12/29/websockets-caution-required, gives a good explanation about the reasons not to use web sockets. The outcome of which is to use a framework, like SignalR, to future proof it. SignalR does use web sockets but also has the intelligence to gracefully degrade to a different messaging method, like polling, if there are problems.
I would definitely recommend using a framework, as not only does it give you more confidence as the code is battle worn, it also allows you to abstract the transportation method of your code and onto a framework. The more you can decouple your solution, the fewer headaches you have late on down the road.
The most popular form implementing a real-time observer pattern within .NET is with SignalR. SignalR is a Microsoft product that was developed to produce real-time applications, like instant chat or real-time notifications. SignalR allows the server to push messages to clients without clients frequently polling the server. In SignalR cases, Microsofts may come up with a better way of real-time messaging within an HTTP2 connection, bundle it up into a later version of SignalR which you get for free by simply updating SignalR within Nuget.
Which Strategy Should You Use?
All the options have different trade-offs and things you need to consider. Option one, waiting for the user is easy, but UI wise isn’t very slick. If your notifications aren’t very time sensitive, then simply waiting for the page to refresh is the easiest and quickest option to implement.
If, however, you don’t want to wait as you need to let the user know instantly about an update, then SignalR is your best option. The classic situation that you’ll find mentioned on the web is stock prices. If you need to display data which can change frequently, waiting for the page to load is sub-optimal. By the time one of your users tries to purchase a stock, without some form of real-time update it is very likely that the price will have changed. if you want to implement real-time messaging then you need to consider things like performance, load balancing, HTTP2. You should definitely use a framework and definitely don’t try to re-invent the wheel yourself!
Using SignalR comes with a cost. When you use web sockets, you keep more connections alive from all the active clients opened, which may cause performance issues. For a small website where you have limited users, this is probably acceptable; if you need to build Facebook, then you need to have a serious think in terms of hardware etc…
When you use polling or long polling instead of web sockets, you’re often wasting bandwidth. Every client will periodically talk to the server to see if anything has updated. If nothing has, then this is a waste HTTP request. Again, if you only have limited users it doesn’t matter too much. If you run a website like Facebook that passive pingback will waste a lot of unneeded resources.
The strategy you need to deploy will be based on your requirements. In my situation, SignalR was the obvious choice. Even thought it involved more code than a simple ‘let the user refresh their page option’, the end functionality worked a lot better and the UI looked a lot slicker.
In my next post, I’m going to write a simple web page that integrates with Episerver. The tutorial will use scheduled tasks to generate new notifications. Clients will register with the server using SignalR and then SignalR will then be used to broadcast and push any updates to the clients.