Client Server Programming with WCF
(Apr 03 2008 - 04:46:38 AM
by Timothy Khouri
) - [print article
Client/server programming isn't a new concept. In fact, it's been around so long that developers can quickly mention a set of problems that will need to be overcome: security, difficulty of implementation, error handling and identity tracking. This article will show how WCF (Windows Communication Foundation) quickly solves all of that and more.
First, lets consider a few other options that have been out there before WCF came about. We'll consider building things "from scratch" by using plain old TCP sockets (which can be implemented in almost any language and environment). Next, we'll talk a little about .NET Remoting and how this made things a lot simpler in terms of development, but was lacking some key functionality, and even caused some big design problems. Finally, we'll compare these two methods (and any similar choices) to using WCF.
Using TCP Socket Connections
TCP connections offer a developer a "raw" methodology for communicating with other computers around the world. While .NET helps with making setup easier by means of the TcpClient and TcpListener classes, you're still left with providing your own means for security, error handling and more importantly, translation of the packets of data.
Because socket connections ultimately just give you the ability to send "bytes" of data across a wire, you're left with this:
byte buffer = new byte;
int numberOfBytesRecieved = myTcpSocket.Receive(buffer);
In order to turn this data into something useful you'll get to enjoy creating several methods just for the sake of re-polling to get the entire message, parsing the data to see what "command" was being sent and reconstructing the parameters into tangible objects.
Other frustrations that come up with using plain old sockets is that you have to constantly check for connection errors. There's no event that fires to let you know when someone disconnected abruptly. As a result, the next time you go to read from the stream, crash, you just got an error.
When you see all the other beautiful classes in the .NET framework, you have to be thinking at this point, "there's gotta be a better, object oriented way to develop connected applications." And there is!
.NET Remoting - A Half-Way Solution
When Microsoft came out with remoting in .NET, suddenly things got a lot easier. Now, instead of raw packets coming across a wire, you were calling actual methods, passing in CLR objects as parameters that would automatically get serialized, transmitted and deserialized on the client end. Once you got the basic framework setup (which isn't very difficult), you could do things like this:
Client clients = myRemotedObject.GetClients();
Please note that these methods are completely made up, but the idea is that the .NET framework took care of all the nasty "raw tcp data" stuff for you, and (behind the scenes) executed your code on the server and returned the result back to your client application.
So you may be saying, "why did we need WCF if we already had .NET Remoting?" There are a lot of good answers to that question, but the ones that I key in on are these:
- .NET Remoting doesn't support two-way communication, whereas WCF does! This means that you can call code from the client to the server, but the server can't call a function back on the client.
- .NET Remoting doesn't have built in events that let the server know when a connection has faulted or closed, nor does it give you a concrete object that represents the connected client as an object. This is important when you want to know for sure when a client has disconnected, even if that was due to an error, to remove it from a list of connected clients (or whatever).
- WCF provides out-of-the-box security measures to ensure that users don't have access to certain functionality until they first "Initiate" and that they can't call privileged methods after they "Terminate."
Basic WCF Infrastructure and Setup
Making a client/server program using WCF is fairly straight forward. We're going to make a server program (a basic Console application), a client program (another Console application) and a communication interface (a class library) to hold common object definitions.
The "service" (or server) will need to be configured to tell WCF the address and port that will be accepting clients. This can be done in code (programmatically), or through the app.config in the "System.ServiceModel" configuration section. Here's how we configured our server:
<security mode="None" />
There's really not a lot going on here. First we configure the service that we will be hosting. In the <service> configuration section, we set the "name" attribute to the class type that we will be hosting. Then, we configure an <endpoint> to tell WCF what address (and port) should map to our service.
The "contract" attribute is the interface that we defined in our class library that both the server and the client have a reference to. Finally, we are going to setup a bindingConfiguration attribute to turn off any encryption or security. This is just to make things easy for our demo.
The client configuration will look very similar to this one, except that it will define the "<client>" tag instead of the "<services>" tag in the app.config. Here's what the client config would look like:
WCF Server Code
Now that our application is configured to host a service, how do we begin accepting connections in the server? Well, the code itself is very simple. Due to saving some space in this article, I'll explain most of it, and then show you just a little to get you excited. At the end of the article will be a full source code example that you can download (a Visual Studio 2008 solution).
First of all, we would need to build our interfaces that will describe what methods are going to be exposed through the service. Also, we'll have to decorate them with a few attributes to tell WCF how to handle the communication. Here is a the server interface code:
[ServiceContract(CallbackContract = typeof(ISingingEelsUser), SessionMode = SessionMode.Required)]
public interface ISingingEelsServer
[OperationContract(IsInitiating = true)]
bool Authenticate(string userName, string password);
[OperationContract(IsInitiating = false)]
[OperationContract(IsInitiating = false, IsTerminating = true, IsOneWay = true)]
The key attributes here are:
- ServiceContract - This tells WCF that the interface can be used as a WCF service. It also says what type of object will be used as a callback to the client in the event of a DuplexChanelBase being used. This is what I was mentioning before that .NET Remorting was missing.
- OperationContract - This attribute basically says "I want to be able to call this method." If you notice, we explicitly say which method is the "initiating" method, and which is the "terminating" one. This means that a client MUST call the Authenticate method first, and that if he calls Disconnect, the connection will end. Again, these built in security functions are not available in .NET Remoting (and certainly not with plain sockets).
After we create our interface objects, we'll now need to create an actual concrete implementation on the server. It will need to implement the ISingingEelsServer interface. Because the app.config file tells WCF how to map that class to the service, nothing more is needed.
WCF Client Code
The client has a little bit more work to do, but not much. It has to create a local representation of the server as well. This class will inherit from System.ServiceModel.DuplexClientBase, which is a generic class, and it will impliment the server interface.
You may be asking, "why do I have to write the server code on the client!?" And the answer is, you don't. All you are doing here is tapping into the WCF object and giving yourself a wrapper class in case you want to do some other functionality in there. When you see the code, it'll make more sense, so here it is:
public class SingingEelsServerConnection : DuplexClientBase<ISingingEelsServer>, ISingingEelsServer
public SingingEelsServerConnection(ISingingEelsUser callbackInstance)
public bool Authenticate(string userName, string password)
return base.Channel.Authenticate(userName, password);
public string GetFavoriteWebsites()
public void Disconnect()
Wrapping It All Up
That's basically the end of it. Now, in your server you simply start "listening" for connections, and in the client code, you make an instance of your SingingEelsServerConnection class and start calling methods. To see how simple it all is, you can download the source code at the end of this article (which we are rapidly approaching).
Please keep in mind that there is a LOT more to WCF than I'm showing here. There will be more advanced articles that will explain features of WCF in more detail, but for now, you can see how to quickly setup a client/server model and begin programming.
Earlier I mentioned that there are events that you can tap into to see if a user disconnects or errors, and those events are:
- OperationContext.Current.Channel.Faulted - Gets called when there is an error on the client's end having to do with the connection. This will get called even if you physically cut your network cable.
- OperationContext.Current.Channel.Closed - Gets called when the connection from the client is closed for any reason. So if you want to clean up some resources made by the connection (whether it's closed gracefully, or via an error) here's where you would put your code.
Last of all, here's the source code for. Check it out for yourself if you have any questions: SingingEels_WCF_Basic_Client_Server.zip