Having the Server Update the Client with SignalR: A Case Study, Part II

In a previous post, I started a case study, looking at an application where it made sense to use Microsoft’s new SignalR technology. The application that I chose is a sales order system that allows users to purchase products. In addition (and here’s where the client-side callback support that SignalR provides becomes useful), users can mark a sales order as “to be expedited.” An “expedited” sales order could go through all of the processing that leads to it being shipped in a few minutes. In that scenario, the client might be willing to stay online and get updates as the order changed progressed through the process. To support that, I wrote some JavaScript code to have the Web page connect to a SignalR message hub. The hub would send out messages about the status of an order as the hub received updates from other, non-Web clients that were processing the order. When a user marked an order as “to be expedited”, my JavaScript code registered with the hub, passing the ID of the sales order the page was interested in. I used SignalR’s support for messaging groups to organize requests in groups by sales order number–the message hub could send a single update to the group for a salesorder and have that message delivered to all of the interested parties.

In this post, I’m going to look at the .NET clients that, while processing a sales order, will also log onto the message hub and send updates to the hub for processing.

One caveat: As I’m writing this, SignalR is still in beta. It’s possible that things will change before SignalR is released, invalidating what I say here. It’s also possible that SignalR will go the way of Microsoft’s Upshot and never get released at all.

Sending Updates

I could have the .NET clients that will be processing the sales order connect to the message hub and get a list of registered sales orders. However, that’s not necessary in this case because expedited sales order have a field indicated whether or not they’re being expedited. As a result, when a client is processing a sales order it will check the Expedite flag on the order and connect to the message hub.

The first step in creating a .NET client that can work with SignalR is, in Visual Studio, to use NuGet to add the Microsoft ASP.NET SignalR Client and the Json.net packages to the project. That’s true even if, as I am, you’re creating a non-ASP.NET client (I’m building my client-side code in WPF). Once that package is in place (and an Imports or using statement added for the Microsoft.AspNet.SignalR.Client.Hubs namespace) you can write the code to open a connection to the message hub.

With the Web client, I was obliged to start the connection with the hub and keep the connection open so that my Web client could receive messages from the hub at any time. However, this .NET client is only sending messages to the hub and not receiving them. Since there is a cost associated with every connection maintained at the server, if there are a lot of .NET clients then it may make sense to start the connection from these clients only when there’s some information to send. For this case, study, however, I’m going to assume that there is only a single program that processes sales order and so I’ll have that program start the connection as soon as the program starts. This means that I’ll be starting the connection in one method (Window_Load, probably) and using the connection in other methods–I’ll need to declare both the hub and connection at the class level:

Class MainWindow
  Private conn As HubConnection
  Private hub As IHubProxy

To open the connection to the message hub, I create a HubConnection object, passing the URL for the server that my hub is executing on. After that, I create the hub by passing the name of my hub’s class (SalesOrderNotifications, in my case) to the HubConnection’s CreateHubProxy method. I then call the HubConnection’s Start method. This is an asynchronous method but, since there’s not much point in continuing if I don’t have the connection started, I use the Await keyword to wait for the Start method to complete. To support the Await keyword, I put the code in a separate method that I’ll declare as Async and call the method from the Window_Load event of my WPF client:

Private Async Sub InitializeHub()
  conn = New HubConnection("http://localhost:49206/")
  hub = conn.CreateHubProxy("SalesOrderNotifications")

  Await conn.Start
End Sub

In some other method, I’ll call the method on my message hub that send out an update message as the sales order’s status changes. For that I use the hub’s Invoke method, passing the name of the method on the message hub I want to call along with any parameters that method requires. My method on the message hub is called UpdateSalesOrderStatus and must be passed the SalesOrder Id and a SalesOrder status. The Invoke method is also asynchronous but, since nothing in my client depends on the method, I’ll use it in “fire and forget” mode: call the method let it complete in the background. That code looks like this:

Public Sub TalkToHub(SalesOrderID As String, Status As SalesOrderStatus)
  hub.Invoke("UpdateSalesOrderStatus", SalesOrderID, Status)
End Sub

When a client gets tired of receiving messages, they can call the stop method on their connection connection’s hub property which will not only break the connection but will also remove them from any groups they are part of.

And that’s it: I have a message hub that accepts clients and routes messages between them. It’s a very cool technology.

Peter Vogel

Type to search blog.learningtree.com

Do you mean "" ?

Sorry, no results were found for your query.

Please check your spelling and try your search again.