Objective
This article will give step by step explanation on how to create a simple duplex
service in WCF.
In call back operation or duplex service, Service can also call some function at
the client .
- Duplex service allows calling back some
operation (function) on the client.
- Duplex service also knows as Call Backs.
- All Binding does not support duplex
service.
- Duplex communication is not standard. They
are absolute Microsoft feature.
- wsDualHttpBinding supports duplex
communication over HTTP binding.
- Duplex communication is possible over
netTcpBinding and netNamedPipeBinding
Steps involved in creating a duplex service
- Create a WCF Service
- Create a call back contract.
- Create service contract
- Implement service and configure the
behavior for duplex communication and call the client function at the
service.
- Configure the endpoint for duplex service
- Create the client.
- Call the WCF Service
Create a WCF Service
- Open visual studio and create a new
project. Select WCF Service application from WCF project template tab.
- Delete all the default generated code.
- If using VS2010, open web.config and
comment serviceHostEnvironment as below.
- If using VS2008 then delete the default
End Point generated.
- Now you are left with empty IService1 and
Service1.svc.cs file.
Create a call back contract
- Open IService1.cs.
- Add an interface in the same file. Give
any name of the interface. I am giving name here IMyContractCallBack
- Create an operation contract in the
Interface.
- Make sure return type is Void.
- Make sure IsOneWayProperty is set to
true.
- There is no need to mark call back
interface as ServiceContract.
Explanation
At the client side, this call back interface will get implemented and on a
duplex channel Service will call the CallBackFunction from the client.
Create service contract
- Open IService1.
- Declare operation contract called from the
client. Make the isoneway to property to true from the service operation
contract also.
- Set the CallBackContract in Service
contract attribute. Set the call back contract as the interface created for
the call back.
Here IMyContractCallBack is name of the
interface user for duplex communication.
So Service contract and call back contract will be as below,
IService1.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
namespace WcfService3
{
[ServiceContract(CallbackContract=typeof(IMyContractCallBack))]
public interface IService1
{
[OperationContract(IsOneWay=true)]
void NormalFunction();
}
public interface IMyContractCallBack
{
[OperationContract(IsOneWay=true)]
void CallBackFunction(string
str);
}
}
Implement service and configure for duplex communication and call client
function
- In service behavior set the instance mode
of the service to percall.
- Create a call back channel
Here I am using OperationConetxt to get current call back channel.
- Now instance of IMyContractCallBack can be
used to make call at the function in call back interface contract at the
client side. Like below ,
Here we are going to call function at the client
side from the operation contract of the service.
Service1.svc.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
namespace WcfService3
{
[ServiceBehavior(InstanceContextMode=
InstanceContextMode.PerCall)]
public class Service1 : IService1
{
public void
NormalFunction()
{
IMyContractCallBack
callback = OperationContext.Current.GetCallbackChannel<IMyContractCallBack>();
callback.CallBackFunction("Calling from Call Back");
}
}
}
Configure the endpoint for duplex service
As we discussed earlier that duplex service is not supported by all type of
bindings. So while configuring the end point for the service we need to choose
the binding supports duplex communication. Here we are going to use
wsDualHttpBinding
- Declare the end point with
wsDualHttpBinding.
- Declare the Meta data exchange end point.
- Declare the host address
- Declare the service behavior
So the service in configuration will look like
Web.Config
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name ="svcbh">
<serviceMetadata httpGetEnabled="False"/>
<serviceDebug includeExceptionDetailInFaults="False"/>
</behavior>
</serviceBehaviors>
</behaviors>
<!--<serviceHostingEnvironment
multipleSiteBindingsEnabled="true" />-->
<services>
<service name ="WcfService3.Service1" behaviorConfiguration ="svcbh" >
<host>
<baseAddresses>
<add baseAddress = "http//localhost:9000/Service1/" />
</baseAddresses>
</host>
<endpoint name ="duplexendpoint"
address =""
binding ="wsDualHttpBinding"
contract ="WcfService3.IService1"/>
<endpoint name ="MetaDataTcpEndpoint"
address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange"/>
</service>
</services>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
Create the client
- Create a console application to consume
this service.
- Add the reference of System.ServiceModel.
In console application project.
- Add the service reference of the service,
we created in previous steps.
Create a duplex proxy class to implement call
back contract
- Right click and add a class in console
application. Give any name; I am giving the name MyCallBack.
- Add the namespace
- Implement call back contract. In our case
it is IService1Callbackand IDisposable.
Note: Since name of the service contract is IService1, so the call
back interface name will be IService1Callback . It is name of service
contract suffixes by keyword CallBack.
- Now implement the call back contract
method in this class.
- Now make a function in this class to
create duplex proxy.
a. Create an instance of InstanceContext and pass the reference of current
class in the constructor of that.
b. Pass this context as parameter of service1client
c. Call the service on this proxy
So, the function will be
For your reference MyCallback class will be as below,
MyCallback.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ConsoleApplication1.ServiceReference1;
using System.ServiceModel;
namespace ConsoleApplication1
{
class MyCallBack :IService1Callback
,IDisposable
{
Service1Client
proxy;
public void
CallBackFunction(string str)
{
Console.WriteLine(str);
}
public void callService()
{
InstanceContext
context = new InstanceContext(this);
proxy = new
Service1Client(context);
proxy.NormalFunction();
}
public void Dispose()
{
proxy.Close();
}
}
}
Call the WCF Service
Create the instance of MyCallBack class and call the callService() method to
call the service.
Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ConsoleApplication1.ServiceReference1;
using System.ServiceModel;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[]
args)
{
MyCallBack
obj = new MyCallBack();
obj.callService();
Console.Read();
obj.Dispose();
}
}
}
Output