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 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.

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 the use the Duplex Channel setting. We will see about Duplex later in this article.

[ServiceContract]

    public interface IService1

    {

        [OperationContract]

        string GetTransaction(int value);

 

    }

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.

[ServiceContract]

    public interface IService1

    {

        [OperationContract]

        void DoTransaction(string value);

    }

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.
 

[ServiceContract]

    public interface IService1

    {

        [OperationContract(IsOneWay=true)]

        void ChangeTransactionStatus(int value);

    }


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 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.
 

 namespace WcfService1

{

    [ServiceContract]

    public interface ITransactionHandler

    {

        [OperationContract (IsOneWay=true)]

        void TransactionDone(int value);

    }

 

    [ServiceContract(CallbackContract = typeof(ITransactionHandler))]

    interface ITransactionService

    {

        [OperationContract(IsOneWay = true)]

        void DoTransaction(string value);

    }

}

 

public class TransactionService : ITransactionService

    {

        public void DoTransaction(string value)

        {

            int TransactionId = 1; //Get TransactionId from database

 

ITransactionHandler callbackHandler = OperationContext.Current.GetCallbackChannel<ITransactionHandler>();

           

callbackHandler.TransactionDone(TransactionId);

        }

    }


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 are not empty.

Conclusion

The Request / Response MEP are used in most cases, because some kind of acknowledgement 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 acknowledgement is mandatory.


Similar Series

  1. Day 1 - WCF Introduction and Contracts
  2. Day 2 - WCF Fault Contracts
 

Next Recommended Readings