Queuing in WCF
This section describes how to use queued communication in Windows Communication Foundation (WCF).
In WCF, the contracts specify what is being exchanged. Contracts are business-dependent or application-specific message exchanges. The mechanism used to exchange messages (or the "how") is specified in the bindings. Bindings in WCF encapsulate details of the message exchange. They expose configuration knobs for the user to control various aspects of the transport or the protocol that the bindings represent. Queuing in WCF is treated like any other transport binding, which is a big advantage for many queuing applications. Today, many queuing applications are written differently from other remote procedure call (RPC)-style distributed applications, making it harder to follow and maintain. With WCF, the style of writing a distributed application is much the same, making it easier to follow and maintain. Moreover, by factoring out the mechanism of exchange separately from the business logic, it is easier to configure the transport or make changes to it without affecting application specific code. The following figure illustrates the structure of a WCF service and client using MSMQ as a transport.
As you can see from the preceding figure, the client and service must define only the application semantics, that is, the contract and implementation. The service configures a queued binding with preferred settings. The client uses the ServiceModel Metadata Utility Tool (Svcutil.exe) to generate a WCF client to the service and to generate a configuration file that describes the bindings to use to send messages to the service. Thus, to send a queued message, the client instantiates a WCF client and invokes an operation on it. This causes the message to be sent to the transmission queue and transferred to the target queue. All the complexities of queued communication are hidden from the application that is sending and receiving messages.
Caveats about queued binding in WCF include:
All service operations must be one-way because the default queued binding in WCF does not support duplex communication using queues. A two-way communication sample (Two-Way Communication) illustrates how to use two one-way contracts to implement duplex communication using queues.
To generate a WCF client using metadata exchange requires an additional HTTP endpoint on the service so that it can be queried directly to generate the WCF client and obtain binding information to appropriately configure queued communication.
Based on the queued binding, extra configuration outside of WCF is required. For example, the NetMsmqBinding class that is shipped with WCF requires you to configure the bindings as well as minimally configure Message Queuing (MSMQ).
The following sections describe the specific queued bindings shipped with WCF, which are based on MSMQ.
The queued transport in WCF uses MSMQ for its queued communication.
MSMQ ships as an optional component with Windows and runs as an NT service. It captures messages for transmission in a transmission queue and for delivery in a target queue. The MSMQ queue managers implement a reliable message-transfer protocol so that messages are not lost in transmission. The protocol can be either native or SOAP-based, such as the SOAP Reliable Message Protocol (SRMP).
In MSMQ, queues can be transactional or non-transactional. A transactional queue allows messages to be captured and delivered in a transaction and then stored durably in the queue. Messages sent to a transactional queue are transferred exactly once in order. You can use a non-transactional queue to send both volatile and durable messages. A message sent to a non-transactional queue does not carry any reliable transfer assurances; thus, messages can be lost.
MSMQ queues can also be secured using a Windows identity registered with the Active Directory directory service. When installing MSMQ, you can install Active Directory integration, which requires the computer to be part of a Windows domain network.
For more information about MSMQ, see ff917e87-05d5-478f-9430-0f560675ece1.
The <netMsmqBinding> is the queued binding WCF provides for two WCF endpoints to communicate using MSMQ. The binding, therefore, exposes properties that are specific to MSMQ. However, not all MSMQ features and properties are exposed in the NetMsmqBinding. The compact NetMsmqBinding is designed with an optimal set of features that most customers should find sufficient.
The NetMsmqBinding manifests the core queuing concepts discussed thus far in the form of properties on the bindings. These properties, in turn, communicate to MSMQ how to transfer and deliver the messages. A discussion of the property categories is in the following sections. For more information, see the conceptual topics that describe specific properties more completely.
The ExactlyOnce and Durable properties affect how messages are transferred between queues:
ExactlyOnce: When set to true (the default), the queued channel ensures that the message, if delivered, is not duplicated. It also ensures that the message is not lost. If the message cannot be delivered, or the message Time-To Live expires before the message can be delivered, the failed message along with the delivery failure reason is recorded in a dead-letter queue. When set to false, the queued channel makes an effort to transfer the message. In this case, you can optionally choose a dead-letter queue.
Durable: When set to true (the default), the queued channel ensures that MSMQ stores the message durably on disk. Thus, if the MSMQ service were to stop and restart, the messages on disk is transferred to the target queue or delivered to the service. When set to false, the messages are stored in volatile store and are lost on stopping and restarting the MSMQ service.
For ExactlyOnce reliable transfer, MSMQ requires the queue to be transactional. Also, MSMQ requires a transaction to read from a transactional queue. As such, when you use the NetMsmqBinding, remember that a transaction is required to send or receive messages when ExactlyOnce is set to true. Similarly, MSMQ requires the queue to be non-transactional for best-effort assurances, such as when ExactlyOnce is false and for volatile messaging. Thus, when setting ExactlyOnce to false or durable to false, you cannot send or receive using a transaction.
Ensure that the correct queue (transactional or non-transactional) is created based on settings in the bindings. If ExactlyOnce is true, use a transactional queue; otherwise, use a non-transactional queue.
The dead-letter queue is used to store messages that fail delivery. The user can write compensating logic that reads messages out of the dead-letter queue.
Many queuing systems provide for a system-wide dead-letter queue. MSMQ provides a system-wide non-transactional dead-letter queue for messages that fail delivery to non-transactional queues and a system-wide transactional dead-letter queue for messages that fail delivery to transactional queues.
If multiple clients sending messages to different target queues share the MSMQ service, all messages sent by the clients go to the same dead-letter queue. This is not always preferable. For better isolation, WCF and MSMQ in Windows Vista provide a custom dead-letter queue (or application-specific dead-letter queue) that the user can specify to store messages that fail delivery. Therefore, different clients do not share the same dead-letter queue.
The binding has two properties of interest:
DeadLetterQueue: This property is an enumeration that indicates whether a dead-letter queue is requested. The enumeration also contains the kind of dead-letter queue, if one is requested. The values are None, System, and Custom. For more information about the interpretation of these properties, see Using Dead-Letter Queues to Handle Message Transfer Failures
CustomDeadLetterQueue: This property is the Uniform Resource Identifier (URI) address of the application-specific dead-letter queue. This is required if DeadLetterQueue.Custom is chosen.
When the service reads messages from the target queue under a transaction, the service may fail to process the message for various reasons. The message is then put back into the queue to be read again. To deal with messages that fail repeatedly, a set of poison-message handling properties can be configured in the binding. There are four properties: ReceiveRetryCount, MaxRetryCycles, RetryCycleDelay, and ReceiveErrorHandling. For more information about these properties, see Poison Message Handling.
MSMQ exposes its own security model, such as access control lists (ACLs) on a queue or sending authenticated messages. The NetMsmqBinding exposes these security properties as part of its transport security settings. There are two properties in the binding for transport security: MsmqAuthenticationMode and MsmqProtectionLevel. Settings in these properties depend on how MSMQ is configured. For more information, see Securing Messages Using Transport Security.
In addition to transport security, the actual SOAP message itself can be secured using message security. For more information, see Securing Messages Using Message Security.
MsmqTransportSecurity also exposes two properties, MsmqEncryptionAlgorithm and MsmqHashAlgorithm. These are enumerations of different algorithms to choose for queue-to-queue transfer encryption of messages and hashing of the signatures.
In addition to the preceding properties, other MSMQ-specific properties exposed in the binding include:
UseSourceJournal: A property to indicate that source journaling is turned on. Source journaling is an MSMQ feature that keeps track of messages that have been successfully transmitted from the transmission queue.
UseMsmqTracing: A property to indicate that MSMQ tracing is turned on. MSMQ tracing sends report messages to a report queue each time a message leaves or arrives at a machine hosting an MSMQ queue manager.
QueueTransferProtocol: An enumeration of the protocol to use for queue-to-queue message transfers. MSMQ implements a native queue-to-queue transfer protocol and a SOAP-based protocol called SOAP Reliable Messaging Protocol (SRMP). SRMP is used when using HTTP transport for queue-to-queue transfers. SRMP secure is used when using HTTPS for queue-to-queue transfers.
UseActiveDirectory: A Boolean value to indicate whether the Active Directory must be used for queue address resolution. By default, this is off. For more information, see Service Endpoints and Queue Addressing.
The MsmqIntegrationBinding is used when you want a WCF endpoint to communicate with an existing MSMQ application written in C, C++, COM, or System.Messaging APIs.
The binding properties are the same as for NetMsmqBinding. However, the following differences apply:
The operation contract for MsmqIntegrationBinding is restricted to taking a single parameter of type MsmqMessage<T> where the type parameter is the body type.
Much of MSMQ native message properties are exposed in the MsmqMessage<T> for use.
To help with serialization and deserialization of the message body, serializers such as XML and ActiveX are provided.
For step by step instructions on how to write WCF services that use MSMQ see the following topics:
For a completed code sample illustrating the use of MSMQ in WCF see the following topics: