Creating a Duplex Service in Windows Communication Foundation (WCF)

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 duplex WCF 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 named IDuplexCallback. Below is the code:

namespace DuplexWcfService
{
    public interface IDuplexCallback
    {
        [OperationContract(IsOneWay = true)]
        void DuplexCallbackFunction(string requestString);
    }
}
Note that the operation contracts in the WCF service are marked as OneWay.
Now create a regular WCF contract named as IDuplexService as shown below
namespace DuplexWcfService
{
    [ServiceContract(SessionMode=SessionMode.Required, CallbackContract=typeof(IDuplexCallback))]
    public interface IDuplexService
    {

        [OperationContract(IsOneWay = true)]
        void FormatString(string institution);
    }
}

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:

  namespace DuplexWcfService
{
    [ServiceBehavior(InstanceContextMode=InstanceContextMode.PerSession)]
    public class DuplexService : IDuplexService
    {
        IDuplexCallback _callback;
        string _requestString = String.Empty;

        public DuplexService()
        {
            _callback = OperationContext.Current.GetCallbackChannel<IDuplexCallback>();    
        }

        public void FormatString(string institution)
        {
            //Make the thread to sleep for 10 seconds
            Thread.Sleep(10000);
            //Format the input data
            _requestString = string.Format("Welcome to {0}", institution);
            //Pass the string to the client through the call back function
            _callback.DuplexCallbackFunction(_requestString);
        }
    }
}

Here is the configuration entry for the servicemodel element in web.config.

<system.serviceModel>
		<services>
			<service behaviorConfiguration="DuplexWcfService.Service1Behavior" name="DuplexWcfService.DuplexService">
				<endpoint address="http://localhost:52775/DuplexService.svc" binding="wsDualHttpBinding" contract="DuplexWcfService.IDuplexService">
				</endpoint>
			</service>
		</services>
		<behaviors>
			<serviceBehaviors>
				<behavior name="DuplexWcfService.Service1Behavior">
					<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
					<serviceMetadata httpGetEnabled="true" />
					<!-- 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 -->
					<serviceDebug includeExceptionDetailInFaults="true" />
				</behavior>
			</serviceBehaviors>
		</behaviors>
	</system.serviceModel>

The binding used is wsDualHttpBinding which supports both per session and dual messaging.



Creating a Duplex Service in Windows Communication Foundation (WCF)

Developing the Client and Consuming the Duplex Service

Add the service reference to the duplex service and name it DuplexServiceReference. Add a form to the Windows application client and implement as shown in the code below.

namespace WindowsAppClient
{
    public partial class DemoForm : Form
    {
        public DemoForm()
        {
            InitializeComponent();
        }

        private void btnDoRequest_Click(object sender, EventArgs e)
        {
            InstanceContext instanceContext = new InstanceContext(new DuplexCallbackHandler());
            DuplexServiceClient client = new DuplexServiceClient(instanceContext);
            client.FormatString("CODEGURU.COM");
        }
    }

    /// <summary>
    /// Callback handler
    /// </summary>
    class DuplexCallbackHandler : WindowsAppClient.DuplexServiceReference.IDuplexServiceCallback
    {
        #region IDuplexServiceCallback Members
        /// <summary>
        /// Callback function
        /// </summary>
        /// <param name="requestString"></param>
        public void DuplexCallbackFunction(string requestString)
        {
            MessageBox.Show(requestString);
        }

        #endregion
    }
}

Note that there is also a class named DuplexCallbackHandler which implements the callback contract. Here is the client configuration entry.

<system.serviceModel>
        <bindings>
            <wsDualHttpBinding>
                <binding name="WSDualHttpBinding_IDuplexService" closeTimeout="00:01:00"
                    openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
                    bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
                    maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
                    messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true">
                    <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                        maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                    <reliableSession ordered="true" inactivityTimeout="00:10:00" />
                    <security mode="Message">
                        <message clientCredentialType="Windows" negotiateServiceCredential="true"
                            algorithmSuite="Default" />
                    </security>
                </binding>
            </wsDualHttpBinding>
        </bindings>
        <client>
            <endpoint address="http://localhost:52775/DuplexService.svc"
                binding="wsDualHttpBinding" bindingConfiguration="WSDualHttpBinding_IDuplexService"
                contract="DuplexServiceReference.IDuplexService" name="WSDualHttpBinding_IDuplexService">
            </endpoint>
        </client>
</system.serviceModel>

We are done, now go ahead and run the application. Fig 1.0 shows the output window.

[output1.jpg]
Fig 1.0

When you debug the application, you will notice that the client will post the request to the FormatString method and continue with its execution. The server method will do the callback independently to the callback method DuplexCallbackFunction on the client application.

Conclusion

I hope this article provided a some insight into the duplex services concept and how it could be implemented in a WCF service. The demo application is simple but I feel that it does well in explaining about the duplex services. I have attached the source code of the demo application along with this article.

Happy reading!

Related Articles





About the Author

V.N.S Arun

I work for an MNC in Bangalore, India. I am fond of writing articles, posting answers in forums and submitting tips in dotnet. To contact me please feel free to make use of the "Send Email" option next to the display name.

Downloads

Comments

  • There are no comments yet. Be the first to comment!

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Live Event Date: May 7, 2014 @ 1:00 p.m. ET / 10:00 a.m. PT This eSeminar will explore three popular games engines and how they empower developers to create exciting, graphically rich, and high-performance games for Android® on Intel® Architecture. Join us for a deep dive as experts describe the features, tools, and common challenges using Marmalade, App Game Kit, and Havok game engines, as well as a discussion of the pros and cons of each engine and how they fit into your development …

  • With JRebel, developers get to see their code changes immediately, fine-tune their code with incremental changes, debug, explore and deploy their code with ease (both locally and remotely), and ultimately spend more time coding instead of waiting for the dreaded application redeploy to finish. Every time a developer tests a code change it takes minutes to build and deploy the application. JRebel keeps the app server running at all times, so testing is instantaneous and interactive.

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds