At one of the Charlotte Alt.Net meetings I gave a presentation on how I utilized a simple Pub/Sub messaging architecture to allow for several applications to communicate across machine boundaries. This blog post won’t be about that system I demoed at the meeting, but it will be about a suggested example that will get the Pub/Sub concept across in a simple way.
The system that is being built to demonstrate the Pub/Sub concept will fulfill the following requirements:
- Simulate a BBQ Smoker
- Monitor the temperature of a BBQ Smoker
- Provide feedback at what temperature the Smoker is currently at.
- Provide visual Alarm indicators that identify three states of the temperature
- Ability to have multiple smokers
- Ability to have multiple monitors monitoring a single smoker
The Pub/Sub Infrastructure was taken from a previous MSDN article written by Juval Lowy. The infrastructure uses WCF as the communications mechanism. The source code I have in my sample project might be a little different than what was in the original MSDN article so I will explain how it is organized in the Visual Studio Solution.
First a little background on what makes up a Pub/Sub Messaging system. A Pub/Sub Messaging system has three components: Broker, Publisher and Subscriber.
The broker is the enabler. The broker’s job is to connect publishers with subscribers. The broker contains a list of subscribers and what messages they are interested in. The broker exposes endpoints that allow for subscribers to subscribe to messages and a publisher to publish interesting messages. In my example solution the broker is a WCF service that is hosted by a console application (Broker.ConsoleHost). Since this is a WCF service it can also be hosted under IIS or a Windows Service just as easily.
The WCF Contract for messages that the broker accepts for the BBQ Smoker is as follows:
Since the broker also manages what subscribers want to subscribe to a contract also exists for subscribers as follows:
The only thing the publisher knows is that when it has anything to publish it simply sends the message to the Broker. The publisher has no idea on the final destination of the message or if there even is a final destination. This promotes a very decoupled system in that the publisher knows nothing about their subscribers. In my example solution the publisher is the Smoker device and it publishes the, Smoker Alarm and Temperature Changed messages. A Smoker Alarm message is published when the smoker reaches a temperature that is too low of too high. A Temperature Changed message is published when the temperature of the smoker has changed at all.
Since the Smoker Temperature is simulated by a slider on the UI here is the event that fires when the slider changes and publishes the Alarm and Temperature changed messages:
The _publish object in the above code snippet is simply a web service proxy that calls the broker.
A subscriber communicates with the broker to tell it what published messages it is interested in. The subscriber in my example solution is the Smoker Monitor. The job of the subscriber is to listen for Smoker Alarm and Temperature Changed messages and display information to the user when these messages arrive. The Smoker Alarm message will turn the display Yellow when the temperature is too low and Red when the temperature is too high. The temperature changed message will update the screen with the actual temperature that came from the smoker.
The subscriber needs to register the class that implements the interface (IMessage) that will be the callback that gets executed when either of messages are received. In my example solution this is done in the constructor of the Form1 class in the Smoker Monitor project as shown below:
Additional logic exists in the SmokerAlarm (callback) method that sets the UI components to the proper color and text based on the alarm state as shown below:
Since the broker is capable of hooking up multiple subscribers to a single publisher you can run multiple monitors across multiple machines all monitoring the same smoker. This is very powerful because the monitors could be providing the same feedback to the user just in a different location of the house or the monitor could be providing feedback via a different means. For example another monitor could be created that sent a text message or a twitter message when the alarm is published. These new monitors can be added without changing the existing contract. Even a third party could create a monitor that did some special thing on published messages and you could run their monitor without changing the broker or smoker.
A zip that contains the entire code for the BBQ Smoker Monitor via Pub/Sub messaging can be found here. Feel free to download the code and look at it in more detail. Also take a look at the ReadMe.txt for additional information on how to run the application.
I hope to expand on this in a later project that will allow me to create an actual embedded device that can detect the temperature of a smoker instead of using a simulated Smoker Device. This embedded device will have to be able to publish the messages to the broker so that a PC does not have to be connected to the smoker.