Building WCF Channels and Bindings

CodeGuru content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More.

In a prior article, https://www.codeguru.com/csharp/csharp/cs_network/internetweb/article.php/c13513/, I introduced you to Windows Communications Foundation. In the article, I gave an overview of what WCF is and how WCF fundamentally works. I shared how WCF classes are divided into the Service Model layer and the Channel Layer and I mentioned that Channels and Bindings are a good place to begin your study of WCF. In this article, you’ll learn how to build Channels and Bindings. First, you’ll look at the anatomy of a channel and then look at how you code a Channel using the WCF classes.

What Is a Channel?

If your Service was the human body, channels would be the sensory nerves of your Service. Sensory nerves carry messages from receptors in your body to your brain. Sensory messages pass through multiple nerves on the way to the brain.

Like sensory nerves, Channels create and transmit messages and pass the messages from one Channel to the next. Instead of interpreting impulses received from your sense receptors, Channels create messages from bytes received on the wire. As discussed in a previous article, the group performing the communication of Channels is often referred to as the Channel Stack.

There are two types of Channels: Transport Channels and protocol Channels. Transport Channels handle communications over the wire. Protocol Channels handle things like decryption and data transformation.

Messages emitted from the topmost Channel in the stack are carried by what WCF calls the Dispatcher to functions you’ve created and mapped to the Contract in your service. The whole arrangement of Channel Stack and Dispatcher looks a lot like the figure below.

A Transport Channel is at the bottom of the Channel Stack. Data (Messages) flow upward from the Transport Channel and through the set of Channels in the Channel Stack. The Dispatcher is really a collection of classes. A complete discussion of the Dispatcher is beyond the scope of this article, but you can read more about the role of the Dispatcher in the WCF documentation.

As you may have guessed, there is a little more to Channels and building a Channel Stack than this description would have you believe. There are many more working pieces living inside a Channel Stack making the Channel Stack do its magic.

Channel Stack Anatomy 101

A Channel stack is composed of Channels, ChannelManagers, and other classes doing specialized work such as translating raw bytes into Messages. This article will focus on the role of Channels and ChannelManagers and leave a discussion of the other classes for a future article.

ChannelManagers are responsible for building and maintaining Channels. ChannelManagers come in two flavors described below:

  • ChannelFactories build and manage Channels used by a Client communicating with a Service.
  • ChannelListeners build and manage Channels used by a Service.

This article focuses on the Service side of WCF, so you’re going to focus on the role of the ChannelListener and Channel in the Channel Stack.

Bindings are the “B” component of an Endpoint. Again, refer to the introductory article for more information. Bindings are a collection of Binding elements. Binding Elements build ChannelListeners and, as stated earlier, ChannelListeners build and manage Channels. The figure below graphically depicts the relationships between the classes.

According to the Microsoft documentation, Channels are decoupled from one another and instead are mediated by the Channel Listener.

Before you look at how ChannelListeners and Channels work together to provide communications in your Service, there is an important idea to understand. A State Machine governs all WCF communication. States in the State Machine are what you would expect: Open, Abort, Close, and so forth. Classes participating in the communication State Machine support the ICommunicationObject interface. For a complete explanation of the WCF communication state machine, see the WCF documentation.

Now that I’ve introduced you to the composition of a Channel Stack, you’re ready to look at how you code a Channel Stack.

The Sample

The sample code is confined to the basics of Channel Stack construction. As stated earlier, the goal of the article is to introduce you to Channel construction. So, the sample code implements a small subset of WCF’s true Channel capabilities.

All Services, WCF or not, typically follow some well-established communication patterns. The WCF documentation refers to the communication pattern as the Message Exchange Patterns, but the term “Shape” is also used to describe the type of interface you use to implement the pattern. The three Message Exchange patterns are summarized below:

  • In the Datagram, or one-way pattern, messages flow from the client to the service.
  • In the Request-Response pattern, data flows from the client to the service and then a separate response message flows back to the client.
  • In the Datagram and the Request-Response patterns, there is a single initiator. In the Duplex pattern, either the Client or the Service can be an initiator and messages flow back and forth.

The sample implements a Datagram pattern because it’s the most basic of the patterns and the simplest to implement. There are many ways to mix the role of ChannelListeners and Channels. My sample design is based on my interpretation of the documentation along with a review of the samples shipping in the SDK.

In the sample, there are three Channels in the stack. A transport channel creates the message and two other protocol channels attach header data to the message.

The State Machine governing WCF communication can invoke Channel functions asynchronously or synchronously. Every Message Exchange Patten contains each invocation style. For simplicity, only the Synchronous style has been implemented.

Also, the sample interacts directly with the Channel Stack. So, nowhere in the sample code do you declare a Contract. To run the samples, you’ll need the latest SDK.

You’re finally ready to look at some code. You’ll start with the Channels and Channel Listeners, understand the binding code, and then invoke the Channel Stack without building other parts of a Service.

The Channels

As stated earlier, the Sample implements the Datagram Message Exchange Pattern. Therefore, the Channels implement the IInputChannel interface.

class TestTransportChannel : ChannelBase,IInputChannel
{
   protected EndpointAddress localAddress;

   public TestTransportChannel(TestTransportChannelListener parent,
                               EndpointAddress address)
      : base(parent)
      {
         ... ...

         this.localAddress = address;
      }

There are two key functions in the IInputChannel, the WaitForMessage and the Receive function. When a message is present, WaitForMessage returns true. Receive then retrieves the message. Below is the Receive message on one of the Protocal Channels.

public Message Receive(TimeSpan timeout)
{
   Message msg;
   MessageHeader mh;

   BigHelper.DisplayMessage("Receive " + this.ToString());

   msg = ((TestLevel2ChannelListener)this.Manager)
   .GetMessage(timeout);

   mh = MessageHeader.CreateHeader
   ("Level2", "http://Level2ns", "2");

   msg.Headers.Add(mh);

   return msg;
}

The Receive function returns a Message object. Message objects are passed throughout the layers of WCF. Refer to the prior article for more information on Message objects.

Now, take a look at the ChannelListener.

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read