What is WCF?
WCF is a Microsoft platform for building distributed and interoperable applications and it keeps data in XML and JSON format that can be understood by any language. WCF service can communicate in XML and JSON message formats with the client.
Message Exchange Pattern in WCF
We know that WCF keeps data in XML or JSON format. When a client sends a request to a service and the service sends a response to the client then the request and response is in XML or JSON format, in other words the message exchange is in the format of XML or JSON between the client and the service.
Now I want to explain why we need the Message Exchange Pattern:
- When we want the calling of the function to not take more time
- We just want to call the function and not want wait for the response.
- When we want that function call is not blocking and at the same time we want something out of the function (response) for our application.
- When we want a two-way communication mechanism.
In WCF there are the following 3 types of Message Exchange Pattern:
- Request/Response
- One way
- Duplex
1. Request/Response
This is the default Message Exchange Pattern. In this pattern the client sends a request to the server and it waits for the response until the server does not stop processing, for example if the client a sends a request to get the name of all users then the service will proceed with it and the client must wait for a response when the service sends a result then the client is free. if we use the void keyword then it will also take more time. The one property to set the pattern of request/response is IsOneWay=false and all the WCF bindings except MSMQ based binding supports the request/response.
By using this diagram it can be easily understood that when the client sends a request it must wait for a response until the WCF process is not finished.
Now I will explain the request/response with the following example.
Step 1: Open Visual Studio 2010.
Step 2: Now go to "New Project" > "WCF" > "WCF Service Application" and add the name of the service.
Step 3: Now after declaring the method inside in the interface here the OperationContract attribute is present in the Message Exchange Pattern and the IsOneWay=false setting shows the Request-Reply Message pattern setting.
-
- [OperationContract(IsOneWay=false)]
-
- string RequestReplyPattern();
Now to implement the code in the .cs file.
- public string RequestReplyPattern()
- {
-
- Thread.Sleep(2000);
-
- return "current time of Service is" + DateTime.Now.ToString();
- }
And then after running the service.
Step 4: Now add the new item from right clcik on Solution Explorer and "Add" > "New Item" > "Web Form".
Now get the controls on Web Form for a Button and 2 labels.
- <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="Message_Contract.WebForm1" %>
-
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
- <html xmlns="http://www.w3.org/1999/xhtml">
- <head runat="server">
- <title></title>
- </head>
- <body>
- <form id="form1" runat="server">
- <div>
- <asp:Button ID="Button1" runat="server" onclick="Button1_Click" Text="Button" />
- <br />
- <asp:Label ID="lblPagedate" runat="server"></asp:Label>
- <br />
- <br />
- <asp:Label ID="lblServicedate" runat="server"></asp:Label>
- </div>
- </form>
- </body>
- </html>
Now we need to add the reference of the service so to do that click on Add Service Reference and then a window will open and in it click on Discover and then the service will be shown and add the service.
Code Behind
-
- protected void Button1_Click(object sender, EventArgs e)
- {
-
- lblPagedate.Text = "Page date is " + DateTime.Now.ToString();
- ServiceReference1.Service1Client sc = new ServiceReference1.Service1Client();
-
- lblServicedate.Text = sc.RequestReplyPattern();
- }
Output
Now from the output the client sends a request from a button to the WCF service and it waits 2 minutes and then it returns the result so for that the client must wait for a response until the WCF service processing is done. If there is an exception then the client also must wait for the response.
The advantages of request/response message pattern is:
- Supports all the bindings except MSMQ-based binding
- If an exception occurrs in the service then it immediately informs the client and developer so the developer can easily get the faults in the service.
The disadvantages of the request/response pattern is:
- The client must wait more time since there is so much processing before the service can send the TimeoutException to the client
2. One way
In the previous pattern the client must wait if the return type is void then also so for that in this pattern if the client sends a request to the service then it has no need to wait for the response. This mode is used when we don't want to show any type of error to the client because when we use the Message Exchange Pattern then it doesn't give any message to the client. We can set these patterns using IsOneWay = true in the service, the exception will be thrown if IsOneWay = true is declared in the output parameter, reference parameter or return value. When we use these modes and if the service is busy with the other service and client sends the request then it can keep the request in the Queue and then the client can do his other work, the client is unblocked and we can set the Queue limit of the request.
The diagram shows that only the client can send the message to the service.
Now I am explaining one-way messages with the following example.
Step 3: The remaining steps are the same and declares the method in the interface and sets the property of OneWay:
-
- [OperationContract(IsOneWay = true)]
- void OneWayMessage();
And now implement the method in the .cs file of the service.
- public void OneWayMessage()
- {
-
- Thread.Sleep(2000);
- }
Step 4: Now in the web form use this code in the code behind:
- protected void Button1_Click(object sender, EventArgs e)
- {
-
- lblPagedate.Text = "on the load time the time is " + DateTime.Now.ToString();
- ServiceReference1.Service1Client sc = new ServiceReference1.Service1Client();
- sc.OneWayMessage();
-
- lblServicedate.Text = "After Calling the service the time is " + DateTime.Now.ToString();
- }
Output
Now the output shows that both times are the same but we specify a 2 minute wait in the service. It happens only because the client sends a request to the server it does not wait for the WCF service processing and it gives the response back if an error occurs then the service also doesn't report to the client.
The following are the advantages of OneWay:
- Clients are unaware of any exceptions of the service.
- It takes less time for the process
- the client is not blocked after a request, the client can do his other work.
- This pattern is doing work like asynchronous
The following are the disadvantages of OneWay:
- If the request exceeds the limit of the queue then it can be blocked by the client.
- The client cannot know whether or not the request is reached successfully
3. Duplex
The duplex pattern implements both of the OneWay and Request/Response message patterns. The client and the service both initiate this pattern. This pattern is more complex than other patterns because the additional communication is added. This mode is used when we want to send the notification to the client about his request being reached successfully or not. It doesn't support all bindings.
As shown in the diagram the client sends a request to the service and it processes the request and gives the response but if the user wants to do his other work then it can also do that and the service provides the notification. For the setting of the Duplex pattern we need to use concurrent mode.
- [ServiceBehavior(ConcurrencyMode=ConcurrencyMode.Reentrant)]
- And for synchronizaion in client machine
- [CallbackBehavior(UseSynchronizationContext=false)]
- Or
- IsOneWay=true
For a better understanding of the Duplex pattern I will explain with the following example.
Before procceding we need to see my previous articles and follow the procedure for self hosting that plays an important role in the Duplex Message Exchange Pattern.
Self hosting of wcf service with console application
In the interface declare the following method.
-
- [ServiceContract(CallbackContract=typeof(IService1CallBack))]
- public interface IService1
- {
- [OperationContract]
- void hello();
- }
- public interface IService1CallBack
- {
- [OperationContract]
- void helloback(string name);
- }
And now implement the method in the .cs of the service:
-
- [ServiceBehavior(ConcurrencyMode=ConcurrencyMode.Reentrant)]
- public class Service1 : IService1
- {
- public void hello()
- {
- Thread.Sleep(50);
- string name="Divya";
-
- OperationContext.Current.GetCallbackChannel<IService1CallBack>().helloback(name);
- }
- }
And now for hosting code in the Console Application:
- static void Main(string[] args)
- {
-
- using (ServiceHost host = new ServiceHost(typeof(Duplex_Message_Exchange.Service1)))
- {
-
- host.Open();
- Console.WriteLine(DateTime.Now.ToString());
- host.Close();
- Console.ReadLine();
- }
- }
And now for testing, create a client to get a new project of a Windows Forms application and here add the reference of the service. For that go to References and Add Service Reference.
And now get 2 controls, a button and a TextBox. And here write the code of code behind:
- [CallbackBehavior(UseSynchronizationContext=false)]
- public partial class Form1 : Form, Duplex_Message_Exchange.IService1CallBack
- {
- public Form1()
- {
- InitializeComponent();
- }
- private void button1_Click(object sender, EventArgs e)
- {
-
- InstanceContext instance=new InstanceContext(this);
-
- Duplex_Message_Exchange.IService1CallBack client = new Duplex_Message_Exchange.IService1CallBack(instance);
- client.hello();
- }
-
- void helloback(string name)
- {
- textBox1.Text = name.ToString();
- }
- }
Output
Advantages of duplex exchange message pattern.
- The user can get the notification of the service without wait.
- The blocking of the client's work is less
Disadvantages of the duplex exchange message pattern.
- It is more complex.
- It doesn't support all bindings.