Step 1.
Run Visual Studio 2008, create a blank solution called 'WCFDuplexService'. Then add a C# Library project to the solution called 'DuplexServiceContract', in this project I'll define the service interfaces which will be exposed via the service host. Add anthoer C# Library project called 'DuplexServiceLib', I'll implement the service contract here. Add a C# Console Application project called 'DuplexServiceHost', for creating a self-hosted WCF Server. Last create a C# Windows Application project called 'DuplexServiceClient'. Now the solution tree should look like this:
Step 2.
In this step I will deal with the service contract. Open project 'DuplexServiceContract' and rename the default .cs file to 'IServiceClass.cs'. And before coding, add a reference to System.ServiceModel, or we can't do anything.
Here's the code of the service contract. 2 interfaces defined, the primary interface is the callback interface, which provides the service-to-client communication, and the secondary one is for client-to-service communication.
namespace Kwan.DuplexServiceContract
{
public interface IServiceDuplexCallback
{
[OperationContract(IsOneWay = true )]
void DuplexCallbackOperation(String msg);
}
[ServiceContract(SessionMode = SessionMode.Required,CallbackContract = typeof (IServiceDuplexCallback))]
public interface IServiceClass
{
[OperationContract(IsOneWay = true )]
void ServiceOperation(String msg);
}
}
Step 3.
Then turn to the project 'DuplexServiceLib', now it's time to implement the service contract. Before doing this, add references to System.ServiceModel and Kwan.DuplexServiceContract.
using Kwan.DuplexServiceContract;
namespace Kwan.DuplexServiceLib
{
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
public class ServiceClass : IServiceClass
{
public IServiceDuplexCallback Callback
{
get { return OperationContext.Current.GetCallbackChannel < IServiceDuplexCallback > (); }
}
#region IServiceClass Members
public void ServiceOperation(String msg)
{
Callback.DuplexCallbackOperation(String.Format( " <{0}> from Client " , msg));
}
#endregion
}
}
Notice that here I did not implement the callback interface, leave it to the client-side. Here just use the interface to work out the code logic.
Step 4.
We need a host, or nothing could be running. With WCF we can create a self-hosted server to supply with the services, no IIS needed ( and of course, IIS can be used, if you don't want to hand-write a self-hosted server ). We make such a host either by hard-coding or config file. Here I use config file for convenience. Here is the config file:
< configuration >
< system .serviceModel >
< services >
< service name ="Kwan.DuplexServiceLib.ServiceClass" behaviorConfiguration ="DuplexServiceBehavior" >
< host >
< baseAddresses >
< add baseAddress ="http://localhost:8080/WCFDuplexService" />
< add baseAddress ="net.tcp://localhost:8000/WCFDuplexService" />
</ baseAddresses >
</ host >
< endpoint address ="" binding ="wsDualHttpBinding" contract ="Kwan.DuplexServiceContract.IServiceClass" />
< endpoint address ="tcpmex" binding ="mexTcpBinding" contract ="IMetadataExchange" />
</ service >
</ services >
< behaviors >
< serviceBehaviors >
< behavior name ="DuplexServiceBehavior" >
< serviceMetadata httpGetEnabled ="true" httpGetUrl ="" />
</ behavior >
</ serviceBehaviors >
</ behaviors >
</ system.serviceModel >
</ configuration >
All the details in this article, like attributes, config files, duplex communication mode or other something, will not be discussed here. If you already have known something about WCF, they're not problems. However, I will write something on these details later this year. Now here is the host code.
using Kwan.DuplexServiceLib;
namespace DuplexServiceHost
{
class Program
{
static void Main( string [] args)
{
using (ServiceHost duplexServiceHost = new ServiceHost( typeof (ServiceClass)))
{
duplexServiceHost.Opened +=
delegate
{
Console.WriteLine( " Service begin to listen via {0} " , duplexServiceHost.BaseAddresses[ 0 ].ToString());
};
duplexServiceHost.Open();
Console.ReadLine();
}
}
}
}
Now, everything is done except a consumer.
Step 5.
Before the work on the client started, you should run the host, or no service reference can be add. OK let's run the host. If succeeded, the console application shows like this:
Then we can add a service reference:
We got it in the project:
Remember the callback interface? Now it is time to implement the interface. For clearity, add a new class to the project
{
class CallbackHandler : TCP.IServiceClassCallback
{
private String _msg;
public String Message
{
get { return _msg; }
}
#region IServiceClassCallback Members
public void DuplexCallbackOperation( string msg)
{
_msg = String.Format( " <{0}> from Tcp Service Host " , msg);
}
#endregion
}
}
Make a simple UI:
Write something for testing
{
public partial class Form1 : Form
{
private CallbackHandler _cb = null ;
public Form1()
{
InitializeComponent();
}
private void button1_Click( object sender, EventArgs e)
{
_cb = new CallbackHandler();
InstanceContext ic = new InstanceContext(_cb);
TCP.ServiceClassClient client = new TCP.ServiceClassClient(ic);
client.ServiceOperation( " Hello from Client " );
}
private void button2_Click( object sender, EventArgs e)
{
textBox1.Text = _cb.Message;
}
}
}
Let's make it run:
We get the desired result.
That's the end for this sample. But several problems came out during this procedure, the client UI usually hangs up, and the host will become so busy that it can't serve anymore. Due to my earlier experience using VS 2005 for WCF developing ( without these problems ), I think, beta 2 is just beta 2, still a distance from the final release.
I am just a beginner in WCF, with lots to learn.