Click here to Skip to main content
Click here to Skip to main content

Push Notifications using RavenDb and SignalR

, 18 Nov 2013 CPOL
Rate this:
Please Sign up or sign in to vote.
A simple email inbox with a NoSQL database that pushes records to the client when a new document is added to the collection.

Introduction

In this article, we will implement a simple email inbox with a NoSQL database that pushes records to the client when a new document is added to the collection.

Reader is assumed to have basic knowledge of RavenDb, DocumentStore, DocumentCollection, etc... as well as basic knowledge of ASP.NET MVC and SignalR framework.

The application is very simple, meant to educate rather than impress the reader cough* Marcelo Ricardo de Oliveira cough*

Background

The Changes API offers a great functionality to subscribe to changes in Documents and DocumentCollections, however, I felt that the documentation was less than adequate, it's my goal here to provide simple working code.

Step by step instructions

RavenDb Setup

  1. Download and extract that latest stable build (Zip Archive) from RavenDB Downloads (2750 at time of writing)
  2. Get the server up and running by executing /RavenDB-Build-2750/Start.cmd if you get the exception "Cannot load Counter Name data because an invalid index '' was read from the registry", run cmd as administrator, then run command lodctr /r then rerun.
  3. You should end up with this:
  4. Go to http://localhost:8080
  5. Create a new database called RavenDbDemo

Project Setup

  1. Run Visual studio as administrator
  2. Create a new MVC project
  3. Create a new Virtual Directory in IIS pointing to the application path
  4. Alter the web site's application pool's Identity to the current user
  5. Add RavenDb reference to the application
  6. Add SignalR reference
  7. Add the RavenDb connection string to web.config
<add name="RavenDB" connectionString="Url=http://localhost:8080;Database=RavenDbDemo" />

Code

To make use of the changes api, we have to create an observer class that implements IObserver<DocumentChangeNotification> to take action when a new document is added to the collection, EmailsObserver.cs does just that:

using System;
using Entities;
using Raven.Abstractions.Data;
using WebUI.Hubs;

namespace WebUI.Models
{
    public class EmailsObserver : IObserver<DocumentChangeNotification>
    {
        public void OnCompleted()
        {
        }

        public void OnError(Exception error)
        {
            //ToDo:handle exception
        }

        public void OnNext(DocumentChangeNotification documentChangeNotification)
        {
            if (documentChangeNotification.Type == DocumentChangeTypes.Put)//new document inserted
            {
                Email newEmail;
                using (var session = MvcApplication.Store.OpenSession())
                {
                    newEmail = session.Load<Email>(documentChangeNotification.Id);//get document by id
                }

                new EmailHub().Send(newEmail.Sender, newEmail.Subject);//notify clients
            }
        }
    }
}

Very well, now we need to subscribe to the changes in the document collection, so, in Global.asax add the function CheckForEmails():

private static void CheckForEmails()
{
    Store
        .Changes()
        .ForDocumentsStartingWith("Emails/")//monitor our Emails document collection
    .Subscribe(new EmailsObserver());
}

Then make sure you call it after instantiating the Document Store:

protected void Application_Start()
{
    Store = new DocumentStore { ConnectionStringName = "RavenDB" };
    Store.Initialize();
    CheckForEmails();
    [....rest of code to register routes, filters, etc...]
}

And in our Index.cshtml:

@{
    ViewBag.Title = "Inbox";
}

<h2>Inbox</h2>
<div class="container">
    <ul id="inbox">
    </ul>
</div>
@section scripts {
    <script src="@Url.Content("~/Scripts/jquery.signalR-2.0.0.js")" 
            type="text/javascript"></script>
    <script src="@Url.Content("~/signalr/hubs")" 
              type="text/javascript"></script>
    <script>
        $(function () {
            $.connection.hub.start().done(function () {

            });

            var email = $.connection.emailHub;
            email.client.addEmail = function (sender, subject) {
           
                $('#inbox').append('<li><strong>' + sender
                    + '</strong>: ' + subject + '</li>');
            };
           
        });
    </script>
}

That's it, run the application, insert a new Email in the Emails document collection.

Then it should be shown on the web page immediately.

Tricky Parts

I ran into some problem when implementing this project:

Exception: "This operation requires IIS integrated pipeline mode."

SignalR exception, project should be run under IIS not the VS server.

Exception: "The requested page cannot be accessed because the related configuration data for the page is invalid."

RavenDb exception, remove handler <add name="All" path="*" verb="*" type="Raven.Web.ForwardToRavenRespondersFactory, Raven.Web" /> from web.config.

Exception: "Cannot access file, the file is locked or in use"

RavenDb exception, make sure the web site's app pool has privileges.

Conclusion

That's it, hope I delivered a clear explanation and a simple application to demonstrate RavenDb push functionality. As always, let me know if you have any comments or questions Wink | ;)

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Omar Gameel Salem
Software Developer
Australia Australia
Enthusiastic programmer/researcher, passionate to learn new technologies, interested in problem solving, data structures, algorithms, AI, machine learning and nlp.
 
Amateur guitarist/ keyboardist, squash player.
 
If you have a question\suggestion about one of my articles, or you want an algorithm implemented in C#, feel free to contact me.
Follow on   LinkedIn

Comments and Discussions

 
QuestionUpdates more samples Pinmemberkiquenet.com25-Nov-13 21:18 
AnswerRe: Updates more samples PinmemberOmar Gameel Salem26-Nov-13 4:11 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.141223.1 | Last Updated 18 Nov 2013
Article Copyright 2013 by Omar Gameel Salem
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid