Category Archives: Programming

SignalR with Load Balanced IIS and SQL Messaging Backplane

A requirement of a recent project was to have asynchronous communication between a set of load balanced servers and multiple web clients. SignalR has the ability to work across multiple servers using a SQL server backplane through the NuGet package. I found a good guide on asp.net‘s website to get the server up and running, but all of the examples involved sending messages to all users at the same time.

Clients.All.addNewMessageToPage(name, message);

In my scenario I needed to signal each user individually.

Clients can be sent to different servers behind the load balancer as they browse the site. Consider this scenario:

1. Client A makes a request to be added to the notification list.
2. The load balancer sends Client A to Server 1.
3. Server 1 registers Client A with it’s local instance of SignalR.
4. Client B requests to notify Client A that some event has occurred.
5. The load balancer sends Client B to Server 2.
6. Server 2 is not aware of the connection between Server 1 and Client A, and the request fails.

With the SQL backplane all of the servers share the same connection list, allowing a message to be sent to a Client A from a Server 2, even though Client A registered with Server 1.

In order to send a message to a single client the server needs to know the specific connection ID to send the message to. SignalR doesn’t offer a way to store a connection ID “key value pair”, so I created one on my own.

In my Hub.cs file I added a method that runs during the client registration:

public void registerClient(long SpecificIdentifier)
{
   HubMethods.RegisterClient(SpecificIdentifier, Guid.Parse(Context.ConnectionId));
}

In the RegisterClient method I store the SignalR connection ID along with a identifier specific to my application. A table stores the ID, the SignalR connection ID, and a timestamp. A procedure was created to clear out the table nightly.

public static void RegisterClient(long SpecificIdentifier, Guid ConnectionID)
{
   using (dbEntities db = new dbEntities())
   {
      Notification notification = db.Notifications.Where(x => x.ID == SpecificIdentifier).FirstOrDefault();

      if (notification == null)
      {
         notification = new Notification()
         {
            ID = SpecificIdentifier,
            ConnectionID = ConnectionID,
            LastModified = DateTime.UtcNow,
         };

         db.Notifications.Add(notification);
      }
      else
      {
         notification.ID = SpecificIdentifier;
         notification.ConnectionID = ConnectionID;
         notification.LastModified = DateTime.UtcNow;
      }

      db.SaveChanges();
   }
}

With the SQL backplane all of the servers share the same connection list, allowing a message to be sent to a Client A from a Server 2, even though Client A registered with Server 1.

When it comes time to send a message to a client, the notification method simply looks up the SignalR connection ID based on the ID specific to our application. The SQL backplane gathers the required information automatically based on the connection ID and the message is sent.

public static void NotifyClient(long SpecificIdentifier, Hub.Statuses Status)
{
   using (dbEntities = new dbEntities ())
   {
      Notification notification = db.Notifications.Where(x => x.ID == SpecificIdentifier).FirstOrDefault();

      if (notification != null)
      {
         String message = String.Empty;

         if (Status== Hub.Statuses.Confirmed)
         {
            message = "Here's the message for confirmation";
         }
         else if (Status == Hub.Statuses.Failed)
         {
            message = "Here's the message for failure";
         }

         try
         {
            IHubContext notificationHub = GlobalHost.ConnectionManager.GetHubContext<Hub>();
            notificationHub.Clients.Client(notification.ConnectionID.ToString()).addMessage(message);
         }
         catch (Exception ex)
         {
            ex.LogToElmah();
         }
      }
      else
      {
         throw new Exception("Unable to find connection");
      }
   }
}

Bootstrap Dropdown Selection

Unlike most dropdown controls in use across the web today, Bootstrap dropdowns don’t natively support selecting items in the list by typing the item you want to select out on your keyboard. On regular dropdowns, if your list has 2 items in it:

<label class="control-label">New / Used:</label>
<div class="dropdown">
   <button id="buttonSearchVehicleNewUsed" class="btn dropdown-toggle " type="button" data-toggle="dropdown">-- Select Type --</button>               
      <ul id="dropDownSearchVehicleNewUsed" class="dropdown-menu" role="menu">
         <li data-val="true"><a href="#">New</a></li>
         <li data-val="false"><a href="#">Used</a></li>
         <li data-val="false"><a href="#">UsedCPO</a></li>
      </ul>
   </div>
</div>

and you open the dropdown, you can normally only use the up and down arrows to select your item. If you modify your list to have dozens or hundreds of items, this can take a significant amount of time.

This plugin allows you to open the dropdown and type “U” to have the first item starting with the letter “U” to become focused. Additional typing will allow a more refined search “USEDC” would jump to the “UsedCPO”. This allows users to quickly get to the item they want. The project is on my GitHub: https://github.com/mlapaglia/Bootstrap-DropdownSelect