Sitecore Dashboard and SignalR

Posted 09/30/2013 by vconcepcion

Just uploaded the Sitecore Dashboard module to Marketplace.

Sitecore Dashboard

The Sitecore Dashboard is a Sitecore app that aggregates real-time data about your site into a customizable widget-based view.

Variations of this idea floated around our team for awhile but have always been based on the need for an interface that provides content administrators with quick and easy access to the tools and information that they most commonly access within Sitecore. One simple step towards addressing this need is to customize the Sitecore Desktop, perhaps by adding some shortcuts or hiding applications that are not relevant to certain users. However, even with shortcuts, a user still has to open up and flip through multiple windows just to get an at-a-glance look at their site.

The Sitecore Dashboard User Guide already provides detailed documentation on how to configure, customize, and extend the above view, including how to add your own custom widgets. Thus, rather than delving into those features further, I'll spend the rest of this post discussing an interesting technical challenge I faced while building the module.

,

A key feature I wanted to build into the Dashboard was to enable it to auto-refresh itself, particularly for the sake of data that is frequently updated or changing. Furthermore, I didn't want clients to repeatedly poll the server for updates unless there was actually new data to display, so I wanted something that could potentially leverage the Sitecore Event subscription model and "push" raised events to listening clients.

After looking into a few ways to meet this requirement, I came across Microsoft SignalR, which is an ASP.NET library for bi-directional client/server communication that supports the web socket protocol, but more importantly provides fallback solutions for older browsers that don't support web sockets. Using this and jQuery, I was able to setup a solution in which Sitecore raises events that are passed to clients through a SignalR Hub. This process is summarized below:

Dashboard architecture

  1. Sitecore server-side event is raised
  2. Dashboard Hub broadcasts message (i.e., name of the event) to all clients
  3. Client-side hub proxy raises jQuery event
  4. Widgets subscribed to jQuery event make AJAX call to get latest data from Web API
  5. Web API gets updated model from Sitecore and returns as JSON
  6. Widget view model object is updated and view is automatically refreshed through declarative data binding (using Knockout JS)

The server-push functionality using SignalR (steps 1-3) consisted of the following code components:

Config to map Sitecore events to event handler

<events>
  <event name="job:started">
    <handler type="Sitecore.Dashboard.Events.EventNotifier, Sitecore.Dashboard" method="OnDashboardEventRaised" static="true" />
  </event>
</events>

Event handler

public static class EventNotifier
{
    /// <summary>
    /// Sends message to all clients containing name of Sitecore event that was raised
    /// </summary>
    /// <param name="sender" />
    /// <param name="args" />
    public static void OnDashboardEventRaised(object sender, EventArgs args)
    {
        Assert.ArgumentNotNull(sender, "sender");
        Assert.ArgumentNotNull(args, "args");

        if (Settings.GetBoolSetting("Dashboard.EnableLiveUpdates", false))
        {
            var scArgs = (SitecoreEventArgs)args;
            var context = GlobalHost.ConnectionManager.GetHubContext();
            context.Clients.All.raiseServerEvent(scArgs.EventName);
        }
    }
}

Class derived from Microsoft.AspNet.SignalR.Hub

public class DashboardHub : Hub
{
    public override Task OnConnected()
    {
        return Clients.All.connected(Context.ConnectionId, DateTime.Now.ToString());
    }

    public override Task OnDisconnected()
    {
        return Clients.All.disconnected(Context.ConnectionId, DateTime.Now.ToString());
    }
}

JS code using SignalR jQuery library to receive messages from server Hub

(function ($) {
    var dashboard = $.connection.dashboardHub;

    dashboard.client.connected = function (id, date) {
        console.log("connected: " + id + " : " + date);
    };

    dashboard.client.disconnected = function (id, date) {
        console.log("disconnected: " + id + " : " + date);
    };

    dashboard.client.raiseServerEvent = function (eventName) {
        $(document).trigger(eventName);
    };

    $.connection.hub.start().done(function () {
        console.log("connection started");
    });
})(jQuery);

In addition to including the files from the SignalR library (I recommend using NuGet to install), I also had to:

  1. Register SignalR Hub routes in your route table (see the end of my previous post on how to add this via an initialize pipeline instead of editing Global.asax)
  2. Include the following script tags on the page:
    <script src="/Scripts/jquery.signalR-1.1.3.min.js"></script>
    <script src="/signalr/hubs"></script>
    

You can check out the full source code for the Sitecore Dashboard on GitHub. Feel free to shoot me any questions or comments.

Share:

Archive

Syndication