Live notifications on your Umbraco site using SignalR

Using the SignalR library it’s possible to push notifications from the server to the clients. In this post I’m going to show how you can publish notifications about newly published documents to a site front page.


For this to happen we need to add four pieces of code:

1. A SignalR Hub that transports messages between server and client.
2. An Umbraco event handler that sends message on document publish.
3. A function that takes necessary information from the document and creates a sendable object.
4. A client side script that activates SignalR and handles the message from the server.

I use the terms Document and Node in the same way as the objects are named within Umbraco. The Document is the editable content object, and it has the event we listen to, but to get the properties we use the cached representation of the document = the Node.

1. The SignalR Hub does not have any additional functionality except for what is built in, so our code is an empty Hub class declaration:

public class NodePublishingHub:Hub
{
}

2. The after document publish event handler sends a subset of node properties through the SignalR hub to the client:

public class PublishEventsToHub : ApplicationBase
{
    public PublishEventsToHub()
    {
        Document.AfterPublish += Document_AfterPublish;
    }
    void Document_AfterPublish(Document sender, umbraco.cms.businesslogic.PublishEventArgs e)
    {            
        var context = GlobalHost.ConnectionManager.GetHubContext<NodePublishingHub>();
        // we need to explicitly update the document cache
        umbraco.library.UpdateDocumentCache(sender.Id);
        context.Clients.NodePublished(GetNode(sender.Id,false));
    }
}

3. The node subset function takes a node and returns only the necessary data (I don’t know if there are any built in functions that already does this). We return it as an object. The Hub will convert it to Json automatically for us.

public object GetNode(int nodeId, bool includeChildren)
{
    var node = new umbraco.NodeFactory.Node(nodeId);        
    return new
    {
        node.Name,
        node.UrlName,
        node.NodeTypeAlias,
        node.CreatorName,
        Properties = node.PropertiesAsList.Select(p => new { p.Alias, p.Value }).ToDictionary(k => k.Alias, k => k.Value),
        node.CreateDate,
        node.UpdateDate,
        node.SortOrder,
        node.Url,
        ParentId = (node.Parent != null) ? node.Parent.Id : -1,
        ChildIds = node.ChildrenAsList.Select(n => n.Id),
        children = includeChildren ? node.ChildrenAsList.Select(n => GetNode(n.Id, true)) : null
    };
}

4. The client side function will initiate SignalR and add the nodePublished function to our client side part of the hub. The function will prepend node information to a ul/li for us (nodepublisher.js):

$(function () {
      // Proxy created on the fly
      var nodePublishingHub = $.connection.nodePublishingHub;
      
      // Declare a function on the chat hub so the server can invoke it
      nodePublishingHub.nodePublished = function(node) {		  
         var updateDate = node.UpdateDate.replace('T', ' '); // quick and dirty format date + time		  
         $('#nodePublished').prepend('<li><a href="' + node.Url + '">' + node.Name + '</a>&nbsp;' + updateDate + '</li>');
      };
            
      // Start the connection
      $.connection.hub.start();
  });

The Template Html is the Umbraco starter kit with the following additions:

<script type="text/javascript" src="/scripts/jquery-1.6.4.min.js"></script>
<script type="text/javascript" src="/scripts/jquery.signalR-0.5.3.min.js"></script>
<script type="text/javascript" src="/signalr/hubs"></script>
<script type="text/javascript" src="/scripts/nodepublisher.js"></script>	
<div class="hotspot">
  <h4>Newly published nodes</h4>
    <ul id="nodePublished">
    </ul>
</div>

Other types of notifications
You can of course send any kind of notifications through a SignalR hub. I’m going to use it to make live updates on the front page when the site users creates registrations on a system on the site. The things necessary to add is invoking a client side function from the server side

context.Clients.NodePublished(GetNode(sender.Id,false));

and having the client side function on the client “part” of the hub:

nodePublishingHub.nodePublished = function(node) {...};

Requirements
For this to work you need to add SignalR to your Umbraco site. And you will also need to add SignalR as a reserved path in your web.config (add key=”umbracoReservedPaths” value=”~/umbraco,~/install/,~/signalr/” ). I tested this on a fresh Umbraco 4.9 site.

Needs to be fixed
This is clearly just a demonstration. To make it useful on a real site one would at least need two things.
The list with newly published pages need to have some initial contents, otherwise the list will be empty when the users arrive, and it will be emptied on page refresh. And also because we use the after publish event we will get notifications also on publish after document edits.

Advertisements

One thought on “Live notifications on your Umbraco site using SignalR

  1. Hello

    I came across your article and found it really interesting. As I am new to SignalR, I wanted to know if it is possible to have more precisions about where to add the functions mentioned above.

    Thanking you in advance for your help.

    Cheers
    Aaeda

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s