One of the more interesting technologies I discovered during my recent trip to Tech Ed 2014 is SignalR, which is a library for ASP.NET that allows real-time communication between the server and browser. This exciting platform enables bi-directional communication between a page and the server, allowing updates to be instantly pushed in either direction. Best of all, SignalR automatically detects the best option for communication based on the capabilities of the client ensuring maximum compatibility across different browsers. To learn more about SignalR and see it in action, I highly recommend you check out this session from Tech Ed: Building Real-Time Applications with ASP.NET SignalR. Today we'll see how you can setup Sitefinity to use this library with a simple notification that fires when a user logs into the backend. Later we'll build a more real-world scenario by building a real-time viewer count for a blog post.
Install the SignalR Library
Like any great library, SignalR is freely available to download via nuget with the full source also available on Github. However, it's important to note that the latest version of SignalR requires ASP.NET 4.5, and Sitefinity is still currently running on ASP.NET 4.0. While it is possible to retarget a Sitefinity project to .NET 4.5, this is not yet officially supported or tested by Telerik. In addition, I like to keep things as simple and native as possible (although we may explore that in a future post or update this when Sitefinity is fully on .net 4.5). So instead we'll instead be using the 1.x version of SignalR, which does support .net 4.0. Specifically we'll use the latest 1.x release version 1.2.1, which can be installed with the following command in Visual Studio:
Install-Package Microsoft.AspNet.SignalR -Version 1.2.1
Next we need to tell Sitefinity to register the routes required by SignalR to generate the required scripts that enable the real-time communication. The simplest way to do this is to add the following code to your site's Global.asax file:
protected void Application_Start(object sender, EventArgs e) {
Bootstrapper.Initialized += Bootstrapper_Initialized;
}
void Bootstrapper_Initialized(object sender, Telerik.Sitefinity.Data.ExecutedEventArgs e) {
if (e.CommandName == "RegisterRoutes") { RouteTable.Routes.MapHubs(); }
}
Be sure that you check for the command name "RegisterRoutes" so that the route is only registered once, or the route will attempt to be registered multiple times, resulting in the error: A route named 'signalr.hubs' is already in the route collection. Route names must be unique.. If your routes are correctly setup, you should then be able to navigate to the page ~/signalr/hubs which should reveal the dynamically generated script to be referenced on your page, which we'll look at next.
Add SignalR Script References
I've created a simple master page, and added the following references:
<script src="/Scripts/jquery-1.6.4.min.js"></script>
<script src="/Scripts/jquery.signalR-1.2.1.min.js"></script>
<script src="/signalr/hubs"></script> <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/js/toastr.min.js"></script>
<link type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/css/toastr.css" rel="stylesheet" />
<link type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet" />
<script src="/Mvc/Views/NotifyWidget/app.js"></script>
Notice that I've referenced the dynamic script from above, plus Bootstrap and the toastr jQuery plugin and CSS which we'll be using to show the real-time notifications, as well as a custom app.js file at the end. This is the fileresponsible for the on-page notifications which we’ll look at shortly.
Create a SignalR Hub and Client Scripts
The last step to wire this all together is to create both a Hub which will be responsible for the Server-side communication, and the associated JavaScript file (app.js from above) to handle the Client-side of things. Because this example is so simple, we only need a blank hub to facilitate the communication, as all of the actual events will happen on the client side. I've done this by creating the simple class below:
using System;
using System.Linq;
using Microsoft.AspNet.SignalR;
using Microsoft.AspNet.SignalR.Hubs;
namespace SitefinityWebApp.App_Custom.SignalrHubs {
[HubName("notice")]
public class NoticeHub : Hub { }
}
For the client side, I created the file app.js which simply starts the Hub communication and attaches a client-side event that will be triggered on-demand from the server. The code is below; we'll look at how to call it in the next section.
(function () {
$.connection.hub.logging = true;
$.connection.hub.start();
$.connection.notice.client.notify = function onNotify(msg){
toastr.info(msg);
};
})();
Putting it All Together
Now that we have a Hub and the client-side code, we need a way to trigger it from the server side. For this simple example, we want to display a toast notification on the page whenever a user logs into the backend. Open up the Global.asax file again and update it to the following, which uses the Sitefinity Event System to subscribe to a logged in event.
protected void Application_Start(object sender, EventArgs e) {
Bootstrapper.Initialized += Bootstrapper_Initialized;
}
void Bootstrapper_Initialized(object sender, Telerik.Sitefinity.Data.ExecutedEventArgs e) {
if (e.CommandName == "RegisterRoutes") {
RouteTable.Routes.MapHubs(); }
if (e.CommandName == "Bootstrapped") {
EventHub.Subscribe<ILoginCompletedEvent>(loggedInEvent);
}
}
private void loggedInEvent(ILoginCompletedEvent eventInfo) {
var noticeHub = GlobalHost.ConnectionManager.GetHubContext<NoticeHub>(); noticeHub.Clients.All.notify(eventInfo.Username + " has logged in");
}
As you can see above, when the LoginCompletedEvent fires, we get an instance of the Notice Hub we created earlier, and use is to dynamically call the notice event on the client side, passing in the username to be displayed on the page. That's all there is to it! Take a look at the screenshots below to see SignalR in action, with the before page showing the blank homepage, and the after shot showing the notification that is fired when the user logs in.
Summary and Next Steps
SignalR is a powerful library enabling real-time communication between a web server and any number of different connected clients. It’s quick to install, setup, and easy to use, abstracting away the complexities of maintaining connectivity. We’ve seen here a simple example of how you can integrate SignalR with Sitefinity. The Event System of Sitefinity opens up many possibilities, such as live product sale notifications, or any other event you might want to monitor. In our next post we’ll create a more real-world scenario by using SignalR to create a live reader count for blog post. Stay tuned! In the meantime as always, I hope this was helpful!
Enjoyed this post and/or found it useful?