Building a "Composite" Transport

I’ve often written about how to write custom channels; transports in particular. In all of the examples I’ve given, the same transport is used for both sending and receiving messages (i.e. HTTP out, HTTP in). This parallelism fails in certain scenarios. For example, WS-Discovery defines a pattern where you send out a UDP Multicast probe (a broadcast request to find a peer), and expect (one or more) HTTP unicast responses back.

Constructing a binding for this scenario requires three pieces:

  1. An outgoing transport
  2. An incoming transport
  3. A correlation mechanism to tie the request to the response

For the transports, you need a BindingElement that returns the outgoing transport from BuildChannelFactory and the incoming transport from BuildChannelListener. One way of doing this is with a CompositeTransportBindingElement. A CompositeTransportBindingElement uses two bindings to build its runtime components. For example, you can pass in a binding that consists of OneWayBindingElement + HttpTransportBindingElement. Or one that contains UdpBindingElement.

For correlation, if you add CompositeDuplexBindingElement to the stack, you can configure a ClientBaseAddress and Service Model will provide correlation using WS-Addressing. You could also provide correlation yourself (which is actually a good topic for later this week :))

The relevant pieces of CompositeTransportBindingElement (posted here) are:

class CompositeTransportBindingElement
        : TransportBindingElement
{
    Binding channelBinding;
    Binding listenerBinding;

    public CompositeTransportBindingElement(
        Binding channelBinding,
        Binding listenerBinding)
    {
        this.channelBinding = channelBinding;
        this.listenerBinding = listenerBinding;
    }

    public override IChannelFactory<TChannel>
             BuildChannelFactory<TChannel>(BindingContext context)
    {
        return channelBinding.BuildChannelFactory<TChannel>(
            context.BindingParameters);
    }

    public override IChannelListener<TChannel>
            BuildChannelListener<TChannel>(BindingContext context)
    {
        return listenerBinding.BuildChannelListener<TChannel>(
            context.ListenUriBaseAddress,
            context.ListenUriRelativeAddress,
            context.ListenUriMode,
            context.BindingParameters);
    }
}

2 thoughts on “Building a "Composite" Transport

  1. Pingback: WCF Team Bloggers

  2. Yuri

    Hi,
    All complicated samples are very nice but nowhere in Internet I can find the simplest one-page sample of how to create just one custom channel that just e.g. prints all incoming messages on server side. It is hard to understand anything when you need to learn about 15 classes and interfaces in one sample. MSDN is of no practical use either being just big junk of methods descriptions.

    Can you please advise a place where I can find simplest examples on custom WCF channels? Thank you!

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *