11

I am trying to craft a facebook-like notification system in our ASP.NET MVC website

In a scenario, the notification system works like this

  1. User1 follow User2 by clicking the follow button in the MVC site
  2. the MVC site send a NotificationItem to the NotificationManager via API request.

POST api/notifications/send

  1. NotificationManager then process this notificationItem and then save it to Azure Table Storage
   class NotificationManager { 
               void SaveNotification(NotificationItem item) { 
                 // save it to azure table storage
                } 
   }
  1. After saving item, the Client (User2) then subscribe to the notificationEvent via the NotificationHub (SignalR hub)

  2. NotificationHub then notify User2 along with the processed notification data.

 class NotificationHub: Hub {
       async Task NotifyUser(string recipientId) {

         // query data from storage and then process it
         var notificationData= await _repo.GetProcessedNotificationDataAsync(recipientId);

         Clients.Group(recipientId).notifyUser(notificationData);

      }
}

I tried to illustrate the CURRENT process and the architecture on this image enter image description here

Now, the one that bothers me is this line of code in step number 5

 var notificationData= await _repo.GetProcessedNotificationDataAsync(recipientId);

What it does behind is query the notificationItem from storage, process it to user readable notification (ei. "User1 is now following you"), then update the status of the notificationItem (IsSent, DateSent) behind.

Needless to say, it performs somehow "heavy" operation. And it will be triggered in real-time every time there is a new NotificationItem to be delivered or broadcast to each subscriber.

Obviously, im talking about performance and scalability issue here. So I researched some possible technology or approach that can solve this problem. And seems like using Azure Service Bus backplane approach is a viable option

SignalR Scaleout with Azure Service Bus

Introduction to Scaleout in SignalR

One particular paragraph explains some limitations on this approach

Server broadcast (e.g., stock ticker): Backplanes work well for this scenario, because the server controls the rate at which messages are sent.

Client-to-client (e.g., chat): In this scenario, the backplane might be a bottleneck if the number of messages scales with the number of clients; that is, if the rate of messages grows proportionally as more clients join

High-frequency realtime (e.g., real-time games): A backplane is not recommended for this scenario.

Now - this one got me thinking, as in my case. Server Broadcast and Client to Client (and something in between) is applicable to what I am trying to achieve.

These are the notification event scenarios that I am currently working on (and its acceptance criteria)

  1. Notify user for new followers (real-time or near-real-time notification)
  2. Chat Messaging (real-time, will see if the chatter is currently typing)
  3. Post a Status (real time or near real time)
  4. Comment in a Post (real-time, will see if the chatter is currently typing)

After hours of thinking - What's in my mind right now (as a result of my lack of experience) is a notification system something like this enter image description here

As you will notice, this is very different from our current design. The current design only uses 1 Azure webrole.

In this, theres a webrole for the website, webrole for the hub, and a worker role to process the notification data. Therefore - distributing the "load" to 3 different roles as well as opening the possibility for scaling-out.

Now - this is my questions in my head right now.

  1. Is this architecture right for what I am trying to achieve?
  2. Since the notification is in the queue - can we achieve "Real-time" notification update on this?
  3. Since we separate the SignalR hub in another web role - how we will handle authorization?
  4. Service Bus Queue or Azure Queue?

Any help will be appreciated.

Note: I intend to only use Azure technologies as this project is really an Azure and .NET oriented.

Linc Abela
  • 797
  • 2
  • 12
  • 26

1 Answers1

0
  1. Yes, your architecture looks like it should do the job, for a load balanced scenario.
  2. If you use ServiceBus Queue it should be, you can integrate pretty easily (use the nuget package SignalRChat Microsoft.AspNet.SignalR.ServiceBus)
  3. Auth will be fine also assuming your application is stateless and auth cookie will still be valid for both roles, assuming they are behind a load balanced scenario.
  4. Service Bus. Here is some more info on how its done. http://www.asp.net/signalr/overview/performance/scaleout-with-windows-azure-service-bus
Isuru Fonseka
  • 601
  • 4
  • 15