WCF Message Exchange Patterns: Day 3

This is Day 3 article. If you have not read Day 1 and Day 2 articles previously, please go through the following articles:
  1. Day 1 - WCF Introduction and Contracts
  2. Day 2 - WCF Fault Contracts

Introduction

 
This article explains exchange patterns. Various types of message exchange patterns and code demonstration for each message exchange pattern.
 

Message Exchange Pattern(MEPs)

 
MEP stands for Message Exchange Pattern. In WCF we are creating services. What does a service do for us? A service does some task on behalf of us or sends a response back from our request. All such communications are done using messages. We send some message as a request and get a message as a response from the service. WCF supports three types of MEPs:
  • Request / Response
  • One-Way
  • Duplex
Now let us see each with an example.
 

Request / Response

 
Request / Response is a very common MEP. To set this pattern we need to set the IsOneWay property of OperationContractAttribute as false. And the default value of the IsOneWay property is false. So ultimately we do not need to set this property. It is set by default. That is why it is very easy to implement.
 
One more thing we should keep in mind is that we should not use the Duplex Channel setting. We will see about Duplex later in this article.
  1. [ServiceContract]  
  2. public interface IService1  
  3. {  
  4.     [OperationContract]  
  5.     string GetTransaction(int value);  
  6. }  
Here you may assume that since we are sending a request and against this request, we are getting something in response, we cannot use a void return type. This is absolutely wrong. You can use a void return type. In this case, the response message is still being sent back to the client. The difference is it sends an empty SOAP body.
  1. [ServiceContract]  
  2. public interface IService1  
  3. {  
  4.     [OperationContract]  
  5.     void DoTransaction(string value);  
  6. }  

Oneway

 
Set the IsOneWay property of OperationContractAttribute to true for a OneWay message exchange pattern. Suppose you send a message to a service. This pattern is used when the service does some operation and you do not want a response back. For example, you want to change the status of a transaction from pending to completed and you do not want to get a confirmation from the service that the status is changed. You can use a OneWay pattern.
  1. [ServiceContract]  
  2. public interface IService1  
  3. {  
  4.     [OperationContract(IsOneWay=true)]  
  5.     void ChangeTransactionStatus(int value);  
  6. }  
Before using this pattern, keep following points in your mind
 
You cannot use FaultContract with this pattern. In my previous article, we have seen FaultContract. For FaultContract there should be a two-way channel. So it is not possible in a Oneway pattern.
 
It is dangerous to send a oneway message since there is no assurance that the operation is processed. In our above example, we sent a message to change the transaction status but there is no assurance that the transaction is changed or not.
 

Duplex

 
The duplex MEP is a two-way message channel. When the client sends a message to the service to instantiate some long-running processing and requires a notification back from the service, a duplex MEP is applicable.
 
There are two types of contacts, ServiceContract and CallbackContract required to implement a duplex MEP. This MEP is declared by associating a CallbackContract with the ServiceContract. It is done through a CallbackContract property of ServiceContract.
  1. namespace WcfService1  
  2. {  
  3.  [ServiceContract]  
  4.  public interface ITransactionHandler  
  5.  {  
  6.   [OperationContract(IsOneWay = true)]  
  7.   void TransactionDone(int value);  
  8.  }  
  9.  [ServiceContract(CallbackContract = typeof(ITransactionHandler))]  
  10.  interface ITransactionService  
  11.  {  
  12.   [OperationContract(IsOneWay = true)]  
  13.   void DoTransaction(string value);  
  14.  }  
  15. }  
  16. public class TransactionService: ITransactionService  
  17. {  
  18.  public void DoTransaction(string value)  
  19.  {  
  20.   int TransactionId = 1; //Get TransactionId from database  
  21.   ITransactionHandler callbackHandler = OperationContext.Current.GetCallbackChannel < ITransactionHandler > ();  
  22.   callbackHandler.TransactionDone(TransactionId);  
  23.  }  
  24. }  
In the preceding example the client sends a one-way message to the TransactionService. After some period of time the service calls back to the client and says TransactionDone.
 
Before using this pattern, keep the following points in mind.
 
In the real world, this pattern is problematic because it requires a connection back to the client. And there may be a chance to not connect back due to firewall and Network Address Translation problems.
 
This pattern doesn't scale very well due to long-running sessions maintained between client and service.
 
Threading problems can occur if either of the Callback channels is not empty. 
 

Conclusion

 
The Request / Response MEP are used in most cases because some kind of acknowledgment is required. In our case, if the client gets TransactionId back at the time of changing the status, he can query further with this TransactionId. So acknowledgment is mandatory.
 


Similar Articles