8

I'm hoping to use SignalR to provide updates to the client, the updates are going to come from a message table which is updated when things happen across the application..

My problem is that the application will have around 500-600 concurrent users and I cant have all them having a connection to the database and constantly polling against the table..

What id like to do is have a single thing{?} polling the table and then updating the hubs rather than each connection polling.. I was thinking of using a singleton for this? so maybe when the application starts something is created that will then do all the work really..

My question is - say I had a singleton that had an event which was fired every time there was an update.. what would the performance be like for say 500 controllers subscribing to this event?

Also.. if there is a better way to do this then pleases say.. this is my first and only idea sadly!

any help would be fantastic!

EDIT: the data is bring provided by a legacy application and I have no control over how the data is entered so database polling will be needed.

ste.

Steoates
  • 3,058
  • 5
  • 27
  • 43
  • what is your database technology? SQL Server, MongoDB, RavenDB, etc? I'm asking cuz some of database technologies out there have a way of firing notification events as soon as data is changed. – tugberk Jan 14 '13 at 15:18
  • @tugberk we use Oracle but Id rather not tie this solution into a database technology – Steoates Jan 14 '13 at 15:32

2 Answers2

14

I'd rather not to poll the database as it would be wasteful. I would approach this problem by opening only one single point of entry for my data (an HTTP API, etc) and then broadcast the update to all connected clients through the SignalR Hub. Brad Wilson has a super cool presentation which demonstrate this approach:

Brad Wilson - Microsoft’s Modern Web Stack, Starring ASP.NET Web API

Here is a code sample for this approach which uses ASP.NET Web API technology for data entry. It uses in-memory dictionary for data store but the data storage technique is not the concern here:

// This hub has no inbound APIs, since all inbound communication is done
// via the HTTP API. It's here for clients which want to get continuous
// notification of changes to the ToDo database.
[HubName("todo")]
public class ToDoHub : Hub { }

public abstract class ApiControllerWithHub<THub> : ApiController
    where THub : IHub {

    Lazy<IHubContext> hub = new Lazy<IHubContext>(
        () => GlobalHost.ConnectionManager.GetHubContext<THub>()
    );

    protected IHubContext Hub {

        get { return hub.Value; }
    }
}

public class ToDoController : ApiControllerWithHub<ToDoHub> {

    private static List<ToDoItem> db = new List<ToDoItem> {

        new ToDoItem { ID = 0, Title = "Do a silly demo on-stage at NDC" },
        new ToDoItem { ID = 1, Title = "Wash the car" },
        new ToDoItem { ID = 2, Title = "Get a haircut", Finished = true }
    };
    private static int lastId = db.Max(tdi => tdi.ID);

    // Lines removed for brevity

    public HttpResponseMessage PostNewToDoItem(ToDoItem item) {

        lock (db) {

            // Add item to the "database"
            item.ID = Interlocked.Increment(ref lastId);
            db.Add(item);

            // Notify the connected clients
            Hub.Clients.addItem(item);

            // Return the new item, inside a 201 response
            var response = Request.CreateResponse(HttpStatusCode.Created, item);
            string link = Url.Link("apiRoute", new { controller = "todo", id = item.ID });
            response.Headers.Location = new Uri(link);
            return response;
        }
    }

    // Lines removed for brevity
}

The full source code for the application which Brad demoed is also available: https://github.com/bradwilson/ndc2012.

The other option, which you don't prefer, is make your database to fire notifications as soon as data is changed. Then, you can pick that up and broadcast it through SignalR. Here is an example:

Database Change Notifications in ASP.NET using SignalR and SqlDependency

tugberk
  • 57,477
  • 67
  • 243
  • 335
  • Although this is a good solution, this just inst possible for me. We are adding a front end on a legacy application and the data in the table will mostly come from database triggers and other database logic. – Steoates Jan 14 '13 at 16:06
  • What if using Azure. Which does not fire events on row changes? Back to polling? – Piotr Kula Apr 25 '14 at 13:29
0

Sorry that this solution is not signalR, but maybe you can get ideas from it.

Here is the full example for download on GitHub

Uffe
  • 2,275
  • 1
  • 13
  • 9
  • That looks pretty good actually, any chance you could provide an example of this working with something like I've mentioned? – Steoates Jan 15 '13 at 08:11
  • Hey, sure... I can create a example where both webclients and (fake) other clients update the database and the controller pushes info out to clients... This can ofcourse be done in a number of advanced ways, but I will keep it stupid and simple (to start with) Edit: will post a link here when I'm done – Uffe Jan 15 '13 at 18:33
  • Thanks mate, that would be fanastic! – Steoates Jan 16 '13 at 08:03
  • Hey Steoates. I´ve created a project... Will just add some comments and then put it on github for you. Probably there tonight. – Uffe Jan 16 '13 at 13:36
  • Page Not Found ! Do you have backup links? – Rick Sanchez Jan 01 '15 at 22:56
  • https://github.com/XSockets/XVA/tree/master/XVA-02-07-PollingDbForUpdates/Any%20OS – Uffe Jan 02 '15 at 11:01
  • This is a dead link – Hitesh Sahu Feb 21 '17 at 07:07
  • https://github.com/XSockets/XVA/tree/master/XVA-02-07-PollingDbForUpdates This will work – Sandeep Kumar Nov 08 '17 at 09:51