Professional Documents
Culture Documents
Microsoft Message Queuing (MSMQ) is an incredibly robust, time-tested messaging server that fulfills a critical role in any communications
platform. What it doesn’t do however, is play well in a service oriented world. MSMQ applications and their developers must be fully aware of
the queue’s they’re communicating with and hand-craft messages to be sent on the wire. In a Service Oriented Architecture (SOA) world, we
don’t think in terms of message in queues, we think in terms of business operations allowing developers to focus on what’s most
important…business operations. Centering application development around these operations enables us to be flexible with not only with our
implementations, but also our communication partners. In addition, the extensibility mechanisms provided when we integrate MSMQ with
Windows Communication Foundation (WCF) are extremely powerful and enable MSMQ developers to do things they never could before.
Getting Started
Launching the demo app
1. Since we’re going to be launch a WCF service that utilizes HTTP port 80, we need to make sure the user we’re launching the service as
has access to that port. There are two ways to achieve that:
a. Explicitly grant permission to this user via a URL ACL.
i. From a command line with administrative permission run:
1. netsh http add urlacl url=http://+:80/ user=DOMAIN\user
ii. Example:
1. netsh http add urlacl url=http://+:80/ user=.\justinw
b. Run Visual Studio with administrative credentials.
2. Open the Visual Studio project that you downloaded for this walk-thru and build it.
3. Hit F5 to run the server side of the application.
4. Find the client side executable of the application in its output directory and run it:
a. "c:\Users\justinwi\Documents\Visual Studio 2005\Projects\MSMQ-WCF-Walk-Thru\Client\bin\Debug\
MSMQChunkingChannelDemo⌂-Client.exe"
1. OrderInfo object (using the Visual Studio link on the desktop, find this file using the solution explorer - CommonResources\OrderInfo.cs)
a. OrderInfo is a simple, user defined, compound object consisting of an image and a string
i. Marked as serializable and denotes datamebers so System.Messagaing and WCF can serialize the object respectively
ii. Also has a helper property which converts the image to/from a byte[]
b. OrderInfo is Submitted by IOrderSubmitters (on the client-side) and processed by OrderWatchers (on the server-side)
2. Client side
a. IOrderSubmitter (Client\IOrderSubmitter.cs)
i. Generic interface for objects that submit orders
ii. Two implementations of this interface so far – the WCFHTTPSubmitter (associated with the “Send with WCF over HTTP”
button) & MSMQ (associated with the “Send with MSMQ” button)
iii. You’ll write a third one that does WCF over MSMQ
b. Each order submitter is associated with a button. When a button is clicked, the corresponding order submitter is created and
used to send the an order
c. The IOrderSubmitter interface makes it easy to add/enable new buttons on the client
3. Server side
a. OrderWatcher (Server\OrderWatcher.cs)
i. Base class with three methods
1. OnOrderFound –
a. raises the OrderFound event to signify the order watcher has found an order
2. WatchForOrders –
a. used to tell an order watcher to start watching
b. takes a string denoting which machine they should watch on
c. invoked when you click “start watching”
d. Must be implemented by derived classes
3. StopWatchingForOrders
a. used to stop watchers
b. invoked when you click “stop watching” button
c. Must be implemented by derived classes
ii. Two implementations so far
1. WCF over HTTP
2. MSMQ using System.Messaging
3. You’ll write the third – WCF over MSMQ
b. The OrderWatcher class makes it easy to define new OrderWatchers in the service application that can all be started/stopped at
the same time.
Takeaways
1. You now understand the architecture of the demo application
2. You can see some similarities between MSMQ and WCF
a. Both have clients and servers (i.e. senders and receivers)
b. Can both communicate using user-defined types
c. Are both very easy to use to send information with (submitter implementations are very simple)
3. MSMQ and WCF differences
a. In MSMQ you think about queues and send messages
i. WCF you define operations and invoke them
ii. Enables you to design your applications in terms of business operations and doesn’t tie you to a certain technology or
implementation of your operation
b. MSMQ’s communication is asynchronous and durable
i. WCF client must be in contact with service endpoint in order to communicate
ii. We’ll address this difference very shortly by combining WCF and MSMQ
c. MSMQ requires you to implement a “message pump” polling for messages and doing the right thing when they come in
i. WCF implements the “message pump” logic for you. All you have to do is do the right thing once a message comes in
4. Enough talk…let’s write some code!
1. Copy the following code into CommonResources\ServiceContracts.cs below the definition for IWCFHTTPOrderContract but within the
namespace scope
[ServiceContract]
public interface IQueuingOrderContract
{
// Queued operations must be marked as one-way since
// two-way communication doesn't make sense for disconnected
// applications
[OperationContract(IsOneWay = true)]
void SubmitOrder(OrderInfo order);
}
a. Note the only difference between this contract and the IWCFHTTPOrderContract is that this one has the IsOneWay property set
to true indicating communication will be from the client to the server, but not vice-versa. This is typical for disconnected or
asynchronous communication where the client and server may not be available at the same time.
2. Define a class that implements your new contract
a. Open the file Server\WCFQueuingOrderWatcher.cs and paste the following
[ServiceBehavior]
public class WCFQueuingOrderWatcher : OrderWatcher, IQueuingOrderContract
{
private ServiceHost serviceHost = null;
serviceHost.Open();
}
3. Points of interest
a. The ServiceBehavior attribute denotes this class defines the behavior of a service operation
b. WCFQueuingOrderWatcher derives from OrderWatcher (like the WCFHTTPOrderWatcher did) and from our newly created
IQueuingOrderContract
c. The only other difference between this OrderWatcher and the WCFHTTPOrderWatcher is the definition of the binding and the
endpoint used for communication.
i. In this case, we use the Net.MSMQ binding and Uri format. We also turn off security since MSMQ is running in
workgroup mode.
ii. This is where all the MSMQ magic happens, from here on out this service will rely on MSMQ for all of its communication
mechanisms enabling a durable, asynchronous, service-oriented, application
#endregion
}
2. Note this client is almost identical to our WCFHTTPSubmitter, the only differences again are the binding and the endpoint Uri and that
the channel we use is of type IQueuingOrderContract.
SubmitOrder(new WCFQueuingSubmitter(ServerTextBox.Text));
b. This code will create a new WCFQueuingSubmitter and will use it to submit and order to any machine indicated in the server
name text box whenever the bottommost button is clicked
2. Server-side
a. Find the definition of the InitializeOrderWatchers method within Server\ServerWindow.xaml\Window1.xaml.cs
b. Add the following code to add your WCFQueuingWatcher to the server’s list of OrderWatchers and to associate it with the
bottommost button in the server UI
watchers.Add(new WCFQueuingOrderWatcher());
watcherTypeButtons.Add(typeof(WCFQueuingOrderWatcher), MCCButton);
c. Now an instance of your WCFQueuingOrderWatcher will be instructed to start and stop as appropriate when the “Start/Stop
Watching” button is clicked in the server UI.
d. You’ll also see that when you send an order using your WCFQueuingSubmitter, the bottommost button on the server will be
highlighted once the order has been received.
Try it out!
1. Take your new durable, service oriented, order processor for a test drive by building it and using the desktop shortcuts to launch the
applications.
a. Be sure to stop all instances of the Server and Client application that are running before building otherwise you’ll get build
failures.
2. Some things to try using your newly functioning “Send with MSMQ + WCF” button:
a. Try submitting orders (drag and image onto the client and click the “Send with MSMQ + WCF” button) when the server isn’t
watching, then start watching
i. Note that scenario won’t work if you try it with the “Send with WCF over HTTP” button
b. Stop the watchers again and submitting lots of orders (hit the button several times) and then look inside MSMQ’s
“WCFQueuingOrders” queue
i. Start->Right click Computer->Manage
ii. Computer Management->Services and Applications->Message Queuing->Private Queues->WCFQueuingOrders-
>Queue messages
iii. You should see a message for each of the orders you submitted in the queue
iv. Start the server watching for orders and refresh your view on the MSMQ queue (F5) to see the messages disappear
c. Try to send to send an order with an image > 4mb in it (from the “Big Images” directory) using the MSMQ + WCF button
i. You’ll get an error, similar to the one you get if you use the MSMQ only button
ii. In the next section you’ll see how to overcome MSMQ’s 4mb message size limitation through WCF!
Takeaways
1. Using MSMQ via WCF is as easy as using any other WCF transport mechanism and enables SOA-centric MSMQ solutions
2. WCF benefits greatly from MSMQ integration, adding durability where previously there was none
What is chunking?
1. When you really need to send large messages over MSMQ, the best way to do so is to break the messages into multiple “chunks”,
each of which is less than 4mb, on the client side and reassemble the chunks on the server side
2. The following exercise demonstrates how to use the Beta version of our new MSMQ Chunking Channel sample. In the near future
we hope to release a sample WCF chunking channel you can use as a reference for your large message scenarios. Sign-up for alerts
on our blog to get notified when the source code is available http://blogs.msdn.com/motleyqueue.
3. The sample chunking channel handles all of the hard work of breaking the messages apart and reassembling for you. All you need to
do is invoke your service operations just like you normally would with WCF.
5. Note there is a new ChunkingBehavior attribute on the operation and the SubmitOrder method now takes a stream instead of an
OrderInfo object.
6. The new chunking behavior attribute signifies that this operation supports chunking
7. We need to use the stream type because the chunking channel supports streaming, in other words, the ability to receive and process
some of the information before all of it is available. For example if you sent a 50 page document using the MSMQ Chunking Channel
sample, you could begin processing the first page even before the last page had arrived.
[ServiceBehavior]
public class MSMQChunkingChannelOrderWatcher : OrderWatcher, IChunkingOrderContract
{
private ServiceHost serviceHost = null;
[OperationBehavior(TransactionScopeRequired = true)]
public void SubmitOrder(Stream orderStream)
{
OrderInfo orderInfo = new OrderInfo("test", BuildBitmap(orderStream));
OnOrderFound(orderInfo);
}
9. Points of interest
a. The primary difference between this OrderWatcher and the WCFQueuingOrderWatcher is the use of the
MSMQChunkingBinding, as opposed to the NetMSMQBinding.
b. You’ll also notice there’s a new OperationBehavior attribute on the SubmitOrder method. This ensure SubmitOrder is
always executed under a transaction guaranteeing even if there’s a service failure once your OrderWatcher starts utilizing
the stream handed in, all of the chunks in your stream will be put back into MSMQ’s queue to be received the next time
your service starts up. This enables end-to-end durability of arbitrarily large messages, a first for MSMQ and WCF.
c. The BuildBitmap method is a simple helper method which builds a bitmap from the stream given to SubmitOrder.
order.Picture.Save(ms, order.Picture.RawFormat);
ms.Position = 0;
channel.SubmitOrder(ms);
}
}
#endregion
}
SubmitOrder(new MSMQChunkingChannelSubmitter(ServerTextBox.Text));
b. This code will create a new MSMQChunkingChannelSubmitter and will use it to submit an order to any machine indicated in
the server name text box when the MSMQ + WCF button is clicked
13. Server-side
a. Find the definition of the InitializeOrderWatchers method within Server\ServerWindow.xaml\Window1.xaml.cs
b. Replace the instances of WCFQueuingOrderWatcher with MSMQChunkingChannelOrderWatcher so the method looks like
watchers.Add(new WCFHTTPOrderWatcher());
watcherTypeButtons.Add(typeof(WCFHTTPOrderWatcher), WCFButton);
watchers.Add(new MSMQChunkingChannelOrderWatcher());
watcherTypeButtons.Add(typeof(MSMQChunkingChannelOrderWatcher), MCCButton);
// Set the shared static event handler for the order watchers
OrderWatcher.OrderFound += new EventHandler(OrderFound);
}
1. Now an instance of your MSMQChunkingChannelOrderWatcher will be instructed to start and stop as appropriate
when the “Start/Stop Watching” button is clicked in the server UI.
2. You’ll also see that when you send an order using your MSMQChunkingChannelSubmitter, the bottommost button
on the server will be highlighted once the order has been received
Try it out!
14. You can now send durable orders from your client to your server that are larger than 4mb!
15. With your watchers stopped, send a large messages and then take a look at MSMQ’s WCFQueuingOrders queue
a. Start->Right click Computer->Manage
b. Computer Management->Services and Applications->Message Queuing->Private Queues->WCFQueuingOrders->Queue
messages
c. You’ll see far more messages than the one you submitted an order for. That’s because the chunking channel broke up the
large messages into smaller ones
16. Now start the order watchers on the Server
a. You’ll see the large messages delivered
b. In MSMQ’s MMC select the WCFQueuingOrders queue and hit F5 to refresh and you’ll see a subqueue under the
WCFQueuingOrders queue. That’s because the MSMQChunkingChannel sorts each of the message chunks from large
messages into their respective subqueues to enable multiple senders and guarantee durability until all of the chunks have
arrived on the destination machine.
17. Note this Beta version of the sample has a race condition exposed by sending several large messages sequentially. This issue will be
resolved before we release the final version of the sample.
Takeaways
18. You can now send arbitrarily large messages over MSMQ by leveraging the MSMQ Chunking Channel sample
19. WCF’s extensibility model makes it possible to add major functional improvements to your communication mechanisms without
fundamentally changing the implementation of your business operations. Note this MSMQ Chunking Channel sample’s functionality
was enabled entirely out-of-the-box with no changes required in the underlying MSMQ or WCF platforms.
MSMQ Interoperability
1. With no changes at all to our MSMQChunkingSubmitter, we can replace our purely System.Messaging-based MSMQOrderWatcher
with a WCF service that can receive and process MSMQ messages.
2. This exercise will demonstrate the ease with which you can start integrating WCF with your existing applications even if you’re
unable to modify your senders and receivers simultaneously
[ServiceContract]
[ServiceKnownType(typeof(OrderInfo))]
public interface IIntegrationOrderContract
{
// Queued operations must be marked as one-way since
// two-way communication doesn't make sense for disconnected applications
[OperationContract(IsOneWay = true, Action = "*")]
void SubmitOrder(MsmqMessage<OrderInfo> order);
}
4. Note SubmitOrder takes a new parameter of type MSMQMessage<OrderInfo>. This enables the WCF channel to provide the same
level of serialization and ease of use the System.Messaging does in a service-oriented way.
5. There’s also a new ServiceKnownType attribute that defines the type of object this service operation supports
6. Finally the Action = “*” parameter to the OperationContract attribute ensures whenever an implementation of an
IIntegrationOrderContract is invoked, it will always invoke the SubmitOrder operation. This is required because native MSMQ
messages don’t have the typical headers WCF messages do indicating which service operation should be invoked. Without those
headers there’s no way for WCF to determine which operation should be invoked so we need to make its choice simple and only
provide one operation per contract.
[ServiceBehavior]
public class MSMQWCFIntegrationOrderWatcher : OrderWatcher, IIntegrationOrderContract
{
private ServiceHost serviceHost = null;
serviceBinding.SerializationFormat = MsmqMessageSerializationFormat.Binary;
[OperationBehavior(TransactionScopeRequired = true)]
public void SubmitOrder(MsmqMessage<OrderInfo> msg)
{
OnOrderFound(msg.Body);
}
}
8. Note the use of the MsmqIntegrationBinding instead of the NetMSMQBinding. This binding enables communication between WCF
and native MSMQ or System.Messaging applications.
9. We also need to set one more property on the Integration binding that we didn’t set on the NetMSMQ binding – the
SerializationFormat. Since we are sending messages from the System.Messaging client using the Binary formatter, we need to tell
our integration binding how to deserialize them.
10. Also note how easy it is to get the OrderInfo object from the msg object in the SubmitOrder method. Since the MsmqMessage is
strongly typed, the Body property automatically returns an object of type OrderInfo.
watchers.Add(new WCFHTTPOrderWatcher());
watcherTypeButtons.Add(typeof(WCFHTTPOrderWatcher), WCFButton);
watchers.Add(new MSMQChunkingChannelOrderWatcher());
watcherTypeButtons.Add(typeof(MSMQChunkingChannelOrderWatcher), MCCButton);
// Set the shared static event handler for the order watchers
OrderWatcher.OrderFound += new EventHandler(OrderFound);
}
Try it out!
14. Build your solution and run the client and server from the desktop shortcuts
15. You’ll now see that orders submitted from your purely System.Messaging submitter can now be processed by a WCF service
16. Note you still get all the durability guarantees that MSMQ offers however you won’t be able to leverage the large message
functionality enabled by the MSMQ Chunking Channel Sample.
Takeaways
17. Integrating WCF with your existing MSMQ applications and enabling them to co-exist is a piece of cake
Conclusion
During this walk-thru you did a lot of cool stuff. You combined the durability of MSMQ with the service-oriented flexibility of WCF. You utilized
WCF’s extensibility model to overcome inherent limitations in your underlying platform and you easily integrated a pure MSMQ client with a
WCF service. You now know a little more about the major benefits you get when you start leverage WCF with your MSMQ solutions.
For more information on MSMQ and/or WCF check out the following: