WCF For Beginners - Part 1: The Basics


Intro

When I first started learning about Windows Communication Foundation (WCF), I quickly got lost with all the terms presented without a high-level picture.  Now that I have mastered this technology better, I feel I can help future developers by providing this short introduction on which to continue to expand their WCF knowledge.


Clients and Services

The main actors in WCF are services and clients.  Services expose functionality/actions which clients can interact with.   For example, a travel agency may choose to provide a service which publishes an action listing all trips on sale.   A customer, using a client (such as a web browser), requests this action (by clicking on a SALE button, for example) to obtain the trips on sale.  Behinds the scenes, the client makes a connection to the service, requesting the "trips-on-sale" action.   The service then replies with the data representing such trips and the client displays the data to the customer.  

Clients are responsible for initiating all communications to the services, while the services simply wait around for a client request to come in, act on it, reply (if necessary) and wait for subsequent requests.  This model of programming is known as service-oriented architecture.  It promotes loose coupling between the different components in a software system, allowing different vendors to provide their own component.  For example, in the example above, we have been talking about a browser (the client) interacting with the remote service but we can easily provide a non-graphical application that interacts with the service and still gets a list of all the trips on sale.

Endpoints

But how does a client know how to reach a service and more importantly, what actions the service can handle? That responsibility falls on the service itself.  The service needs to expose this information to potential clients via something called an endpoint

An endpoint is composed of 4 elements (address, binding, contract and behavior) which collectively describe what the service can do, in what format the data will be provided and how clients can reach the service.   In order to make sense of the terms used to describe the elements of an endpoint, I will use a real-life analogy as an example:  You are tasked with getting an important message to a recipient on the other side of the city at 1600 Pennsylvania Avenue and it must make it there by a specific time.

Addresses

The most obvious element of an endpoint is its address.  It tells clients where to reach the service.  In our real-life example, that would be 1600 Pennsylvania Avenue and in a computer, it may be a URL such as mytravelagency.com.  WCF defines an object named EndpointAddress to hold this address.  It contains some other additional properties which I won't go into detail now to keep this introduction simple.

Bindings

The next element in an endpoint is its binding.  I found this to be the hardest one to understand when I was learning WCF.  Bindings specify how a service interacts with its clients.  It will specify attributes such as the transport, encoding and security.  If these terms mean nothing to you,  let's go back to our real-life example. 

In order to send your very important message, you must first select the method of transport: a courier on a bicycle, a courier in truck, or courier in a helicopter. Obviously, each of these couriers has a reliability risk of getting your message to its destination on time.  The courier on a bicycle may be struck by a car, the one in truck could get delayed in gridlock traffic, while the one on the helicopter has the best chance of overcoming the obstacles that the others face.  Once the message is received, how can you be sure it is understood by the recipient?   It must be written in a language that she understands.   We call that the encoding.  Finally, to prevent the courier from eavesdropping on our message, we want to encrypt it in such a while that only the recipient can read it.  This is the security element.

So a service's bindings defines one or more ways in which a client can communicate with it.  In the real-life example above, you may want to send the message via a helicopter but if your recipient doesn't have a helipad or the airspace around her building is restricted, it makes no sense for you to use that as the transport.  Similarly, if the recipient only speaks English but you send your message in Russian, she will not be able to understand it (decode it).  WCF defines an object named Bindings to hold the attributes (called elements) described above

Contracts

The 3rd element in an endpoint is the contract.  Contracts simply spell out what functionality (operations) the service can provide, how to specify any inputs it may be required to act on your request and how the data will be provided back to you.  For example, it makes no sense to send a message to 1600 Pennsylvania Avenue that says "List trips on sale" as that it's not an function the entity at that address can provide.  Thus a service must provide all the functions it can support and the inputs and responses for each of those functions.  Any slight deviation from that contract and the service cannot provide the clients what they seek.  We'll spend more time on contracts later when creating our first service.

Behaviors

The final element of an endpoint are the behaviors.  This oddly-named property just allows you to customize the service at runtime.  For example, using the IEndpointBehavior Interface, you can add your own code that examines all the incoming/outgoing messages.  This may be useful if you want to add some logging to your WCF stack.

Configuring Endpoints

You can define and configure endpoints programmatically in your code or use an external configuration file (such as app.config or web.config.  More on these later).  While you may be tempted to define your endpoints in code, I'd encourage you to consider leaving that to the configuration file.  In doing so, you (or the users of your application) can easily re-configure your endpoint (add different transports or encoding, for example) without needing to recompile your code.

Summary

To summarize, a WCF endpoint defines how to reach a service, how to talk to it and operations the service will provide.

Messages

All communication exchanged between clients and services are done using a WCF object called a Message.  It doesn't matter what the data being exchanged is (a picture, text, etc).  WCF will simply treat it all as a message.  It is up to the clients and services to insert/extract their data into/from the payload area of the message.  Headers associated with the message will be use by WCF to further route those messages.

Message Exchange Patterns

The interaction of how clients exchange messages with the services is termed message exchange patterns (MEPs).   WCF supports 3 types of message patterns.

Request-Reply

The most common pattern used is the request-reply, which is easy to understand as the client making a request and the service providing a reply.  The client will wait for a reply and no other work will be performed until the reply arrives or WCF times out the request.  The reason this is a very common pattern is that most services want to consume data.  They want to get information from a server back to the user, eg, what is the current stock price? What is on my schedule for today? 

Continuing our example of a travel agency website, a client can press the ON SALE button, thereby making a request to get all trips-on-sale and the service will reply with the discounted trips.


A typical request-reply message pattern where the client makes a request and its execution stops until the reply is received.

Obviously, pausing the entire client application while the request is outstanding will lead to a very unpleasant experience (e.g. the browser may temporarily freeze while it waits) so there are other mechanisms for allowing the application to handle other work while it waits for the results.  In this case, the request is then said to be executing asynchronously.  We will talk about this case later but for now, understand that the default behavior for the request-reply is to wait for the reply (that is synchronously).  A plus for this approach is that the service can inform the client of any problems it found with its request.  The service can generate a fault or exception as a reply message to trigger the client to handle unexpected problems.

One-Way

A second message pattern is one where the client simply sends a message to the service and doesn't expect a reply.  This is called the one-way pattern.  Note that there is no reply from the service so the client can't be certain that its message was received by the service. Furthermore, even if the message was received but during its handling, the service encountered a problem, there is no mechanism for notifying the client of such a problem.  One important aspect of this pattern is that from the perspective of the client, the call is going to appear to be asynchronous.  Namely, it is going to send the message and continue its execution.   While it may appear that way, this is not 100% correct... if the service is running slower and can't process the incoming requests fast enough, an incoming message can't be accepted and will block the client.  We'll simulate this later when we look at code.  

This pattern can used for sending status or metrics to the service or for periodically saving data a customer may be typing into a browser from (such as when you edit a wiki document).  In our travel agency example, you may use the one-way messages when a customer clicks on the icon to add a trip to her "favorite trips"  list.

One-Way pattern sends a message but does not wait for a reply.


One-Way messages are used in support of a queuing applications, which I won't get into here to prevent information overload.  Basically, one-way messages are stored in a queue which can be later retrieved by the recipient, thereby allowing complete decoupling of the message exchange.


Duplex / Callback

So far we have seen message patterns where the client is the one who initiates sending messages to the service.  But what if you want the service to also send its own independent messages (ie not as a reply to a client message)?  For that, you will need the duplex pattern.  This pattern is sometimes referred as the callback pattern and it is a reference to how it is typically use.  It allows the  service to send a notification (or callback) to the client on its own time.

Suppose that in our travel agency example, the customer hits the Buy button on a trip and it takes a minute to process the order.   Which pattern makes sense to use for this interaction?  The Request-Reply would cause the user to experience a 1-min freeze, which is not acceptable.  The One-Way pattern will not give her any indication that the purchase succeeded.  This is where the callback pattern comes in.  The service can use its own message to tell the client when the purchase is complete.  In reality, this pattern is no more than two One-Way communication (one in each direction). 


Duplex communication between the client and service.  Each uses its own one-way pattern to exchange messages.


References


What's Next?

Next, let's create a WCF Service: WCF For Beginners - Part 2: Creating A WCF Service










© Roger Cruz - All rights reserved