Specializations

Friday, March 29, 2013

Windows Communication Foundation (WCF) Support for Duplex Service


What is a Duplex Service?

A service is an application which will reside at a single place say a server and can be consumed by multiple client applications. In a normal scenario what happens is the client will send the request, wait for the response and once the response is fetched the client will proceed with its further execution. In other words the client will be waiting until the server sends back the response; this is because the service is not capable of posting a response on its own. To solve such issues the duplex service comes into play. Duplex services are ones which are able to perform a client call back, so that the client doesn't have to wait for the response, it can simply post a request and continue with its further execution. In simple words it constitutes a dual communication between the client and the server, which is client to server and server to client.

Windows Communication Foundation (WCF) Support for Duplex Service

WCF provides the support for creating a duplex service. It allows the clients to perform asynchronous calls to the WCF services and in turn the WCF service can make a callback to the client and provide the result.
All the extra stuff that needs to be done for a duplex WCF service is shown below:
  1. Create a Callback contract along with the regular WCF service contract.
  2. Have a handler class implementing the callback contract on the client.
  3. The instance of the callback handler class should be passed through the constructor of the proxy class.
  4. Once the operations are complete make sure the callback method is invoked by the service and the result is ready to be given to the client.
The above points may be a little perplexing, but in the later part of this article we will create a duplexWCF service which should be a clarifier.

Things to Watch Out For

While developing a WCF duplex service I could think of a couple of important things to pay special attention to:
  1. It only can work with the InstanceContextMode.PerSession mode.
  2. The binding used should support both PerSession mode and also dual messaging.
  3. The client configuration should define the ClientBaseAddress attribute in the binding element.

Demo Application

Now let us create a demo application which will constitute a WCF based duplex service and a Windows application client consuming it. The basic idea would be to pass an institution name from the client to the service, the result string would be formatted based on the given input data from the client request and the formatted result string will be passed to the client through a callback which would then be displayed in a message box.
  1. Create a blank solution and name it as WcfDuplexServiceDemoSolution.
  2. Add a new WCF service application to the solution.
  3. Add a new Windows application to the solution.

Developing a WCF Duplex Service

Let us now go and develop the WCF duplex service. Firstly create a callback contract namedIDuplexCallback. Below is the code:
  1. namespace DuplexWcfService
  2. {
  3.    public interface IDuplexCallback
  4.    {
  5.        [OperationContract(IsOneWay = true)]
  6.        void DuplexCallbackFunction(string requestString);
  7.    }
  8. }
  9. Note that the operation contracts in the WCF service are marked as OneWay.
  10. Now create a regular WCF contract named as IDuplexService as shown below
  11. namespace DuplexWcfService
  12. {
  13.    [ServiceContract(SessionMode=SessionMode.Required, CallbackContract=typeof(IDuplexCallback))]
  14.    public interface IDuplexService
  15.    {
  16.  
  17.        [OperationContract(IsOneWay = true)]
  18.        void FormatString(string institution);
  19.    }
  20. }
In the above code note that the SessionMode.Required and the callback contract type are provided in the ServiceContract attribute. Add a .svc file named DuplexService.svc. Go to the code behind the DuplexService.svc which is DuplexService.svc.cs. Implement the WCF contract as shown below:
  1. namespace DuplexWcfService
  2. {
  3.    [ServiceBehavior(InstanceContextMode=InstanceContextMode.PerSession)]
  4.    public class DuplexService : IDuplexService
  5.    {
  6.        IDuplexCallback _callback;
  7.        string _requestString = String.Empty;
  8.  
  9.        public DuplexService()
  10.        {
  11.            _callback = OperationContext.Current.GetCallbackChannel<IDuplexCallback>();    
  12.        }
  13.  
  14.        public void FormatString(string institution)
  15.        {
  16.            //Make the thread to sleep for 10 seconds
  17.            Thread.Sleep(10000);
  18.            //Format the input data
  19.            _requestString = string.Format("Welcome to {0}", institution);
  20.            //Pass the string to the client through the call back function
  21.            _callback.DuplexCallbackFunction(_requestString);
  22.        }
  23.    }
  24. }
Here is the configuration entry for the servicemodel element in web.config.
  1. <system.serviceModel>
  2. <services>
  3. <service behaviorConfiguration="DuplexWcfService.Service1Behavior" name="DuplexWcfService.DuplexService">
  4. <endpoint address="http://localhost:52775/DuplexService.svc" binding="wsDualHttpBinding" contract="DuplexWcfService.IDuplexService">
  5. </endpoint>
  6. </service>
  7. </services>
  8. <behaviors>
  9. <serviceBehaviors>
  10. <behavior name="DuplexWcfService.Service1Behavior">
  11. <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
  12. <serviceMetadata httpGetEnabled="true" />
  13. <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
  14. <serviceDebug includeExceptionDetailInFaults="true" />
  15. </behavior>
  16. </serviceBehaviors>
  17. </behaviors>
  18. </system.serviceModel>
The binding used is wsDualHttpBinding which supports both per session and dual messaging.

No comments:

Post a Comment