Message exchange patterns are a standard design that tells how the communication between WCF service and client should happen.
It decides protocols for communication channels to exchange messages between service and clients and help interoperability. WCF supports three message exchange patterns One Way, Duplex, Request-response. This blog also explains how you can implement Duplex contract services.
One Way message exchange pattern is like short term memory loss, it just fires the execution and forgets about the response. It is useful when the client does not require the response back like changing the status of the order, logging some noncritical operations. If you are using MSMQ bindings then One-way mep is the best choice for communication as the client just needs to call the queue and the execution of the task is totally depends on the queue. For marking the operation as one way use IsOneWay = True.
[ServiceContract]
public interface IOrders
{
[OperationContract(IsOneWay=true)]
public void CompleteOrder(int orderID);
}
Note that using a One-way operation contract with fault contract or transaction contexts is not possible.
In Request-response message exchange pattern, client sends the message to WCF service and the service sends back some response with required processing. This is the most used pattern in SOA as much real-time operation requires some status or data back as a response. Using this pattern with the void return type operations empty SOAP body will be sent to the client as a response. For marking operation as Request-response you do not have to do anything as the default property of IsOneWay is false.
[ServiceContract]
public interface IOrders
{
[OperationContract]
public void PlaceOrder(Order order);
}
The duplex pattern is a two-way message channel where service and client can communicate independently with each other and execute operations. The client should provide the appropriate endpoint using it service should be able to send messages. In a real-time applications, the Duplex pattern is complicated as its service required active connection and open firewalls of the client which is usually avoided because of security. Most of the Duplex contracts require long-running sessions at cost of performance.
[ServiceContract]
public interface IOrderDuplexCallback
{
[OperationContract(IsOneWay = true)]
void ShowShipmentDetails(Delivery delivery);
}
[ServiceContract(Namespace = "http://NorthwindServices/OrderService",
SessionMode=SessionMode.PerSession,
CallbackContract=typeof(IOrderDuplexCallback))]
public interface IOrder
{
[OperationContract(IsOneWay = true)]
void PlaceOrder(Order order);
}
The difference between Request-response and Duplex pattern is, Request-response pattern requires the response on the same communication channel whereas Duplex will create a separate communication channel to return a response to the client.
This part of the article describes step by step defining and creating WCF duplex contracts. The duplex contract enables service and clients to communicate with each other without depending on each other. Duplex communication requires the client to provide a channel on which service can trigger operations..
Create a new WCF Service library as suggested in Create a new WCF service library and test using WCFTestClient. This article will give you basic service implementation.
The Duplex contract requires ServiceContracts with One Way and void OperationContract.
Add a new Service Contracts to the project
A primary contract which will be called by client to service. It uses SessionMode.PerSession to maintain each session data.
[ServiceContract(Namespace = "http://NorthwindServices/OrderService",
SessionMode=SessionMode.Allowed,
CallbackContract=typeof(IOrderDuplexCallback))]
public interface IOrder
{
[OperationContract(IsOneWay = true)]
void PlaceOrder(Order order);
}
CallbackContract which will be called by service to the client. As it is mentioned as a callback contract for IOrder WCF will add ServiceContract so no need to mention it explicitly.
public interface IOrderDuplexCallback
{
[OperationContract(IsOneWay = true)]
void ShowShipmentDetails(Delivery delivery);
}
Implement IOrder interface with PlaceOrder operations.
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
public class OrderService : IOrder
{
public void PlaceOrder(int orderID)
{
//Add code for placing orders
// In real application you can use it to update clients
// as and when the shipping status change.
// You can call this method from other internal classes
// to update shipping like shipped, in transit, delivered.
Callback.ShowShipmentDetails(string.Format
("Your order has shipped with tracking number {0} ", 22298889844));
}
/// <summar>
/// Read only public property to give access to callback contract
/// </summary>
public IOrderDuplexCallback Callback
{
get
{
return OperationContext.Current.GetCallbackChannel
<IOrderDuplexCallback>();
}
}
}
Open the app.config file and the endpoint for Order Service. For the duplex contract, we will use wsDualHttpBinding.
<services>
<service name="NorthwindServices.OrderService">
<host>
<baseAddresses>
<add baseAddress = "http://localhost:7741/NorthwindServices
/OrderService/" />
</baseAddresses>
</host>
<endpoint address ="" binding="wsDualHttpBinding"
contract="NorthwindServices.IOrder">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding"
contract="IMetadataExchange"/>
</service>
</services>
Host this OrderService as suggested in Hosting WCF service in IIS. or hosting in Windows service.
Add the client application as suggested in an article for Hosting service in the previous step.
Add a class with the name OrderCallback to the client application. This class will implement the callback contract interface. Add a reference to your service in a class by using keywords.
using Northwind.OrderServiceRef;
public class OrderCallback : IOrderCallback
{
public void ShowShipmentDetails(string TrackingID)
{
Console.WriteLine(TrackingID);
}
}
Open the program.cs from the client console application and add the below code. It creates the InstanceContext of callback and hit the service operation.
static void Main(string[] args)
{
OrderCallback callback = new OrderCallback();
InstanceContext context = new InstanceContext(callback);
OrderServiceRef.OrderClient client = new OrderClient(context);
client.PlaceOrder(1234);
Console.Read();
}
Add the breakpoints in OrderCallback.cs and main methods. Run the console application by pressing F5. After calling service operation it calls the ShowShipmentDetails from OrderCallback.cs and prints the message send by service.
Nice article