• Feeds

    Subscribe in a reader

  • Ads

Standard bindings in Indigo

One thing that you'll hear over and over again when it comes to Indigo are the "ABC's" of Indigo endpoints. Endpoints have an Address (which is where the messages go), a Binding (which is how the messages get there), and a Contract (which is the set of message exchange patterns that the endpoint supports). This post is about bindings.

Bindings are all about the mechanics of delivering a message to an endpoint. Bindings cover things like transport protocol, message encoding, security requirements, and session correlation. All of these things affect how messages to and from the endpoint. Externally, Indigo describes bindings to others using WS-Policy. Internally, Indigo uses binding information to build up a channel stack capable of implementing the requirements expressed by a particular binding configuration.

Indigo pre-defines a set of standard bindings intended to provide intelligent defaults for the most common scenarios. For example, there's a standard binding defined for interoperability with the WS-I Basic Profile. There are other bindings defined that use the WS-* protocols to apply security and reliability by default. And there are a couple of standard bindings that are specifically defined for Indigo/Indigo scenarios. The WinFX documentation has some good information on the standard bindingshere. The docs do a pretty good job of giving a high-level explanation of what each binding is intended for and the various tradeoffs inherent in using each one.

If you don't like the any of the standard bindings for whatever reason, you can define your own custom bindings where you can stack up channel behaviors any way you like. So if you want a duplex HTTP channel that uses reliability but not security, that's easy to hook up with a custom binding. This gives you a tremendous amount of flexibility that's accessible completely from configuration, so you can twiddle all these knobs without having to touch your code (of course, you can specify bindings imperatively in code too if that's your style).

The standard bindings are really just sets of common configurations that have been given well-known names for convenience. As such, it's possible to define an equivalent custom binding that means the exact same thing as a standard binding. There's generally no real-world reason to do this, but it's nice to know that there's nothing "magical" about the standard bindings. To illustrate this, I've included equivalent definitions for each of the standard bindings available in the March CTP below. But before I unleash a bunch of angle brackets on you, there are a couple things I want to make clear:

  1. This is plumbing -- you don't need to understand these bindings at this level of detail to use Indigo effectively. I'm posting this for illustrative purposes and because I think the type of people who read my blog might be interested in this stuff.
  2. This is the state of the world as of the March CTP. It's a Tech Preview, so this may change before RTM. Fair warning :)

So for those of you who like knobs, here's the list of the Indigo standard bindings and all their associated configuration options, decorated with angle brackets for Your Reading Pleasure (I generated this by importing metadata using svcutil.exe, which (in the CTP, at least) doesn't know about standard bindings).

<bindings>
 <customBinding>

  <!-- The BasicProfileBinding, which is an HTTP-based
       binding compatible with the WS-I Basic Profile -->

   <binding configurationName="BasicProfileBinding">
     <httpTransport hostnameComparisonMode="StrongWildcard"
                    manualAddressing="False"
                    maxMessageSize="65536"
                    authenticationScheme="Anonymous"
                    bypassProxyOnLocal="False"
                    mapAddressingHeadersToHttpHeaders="True"
                    realm=""
                    transferTimeout="00:10:00"
                    useSystemWebProxy="True" />
     <textMessageEncoding maxReadPoolSize="64"
                          maxWritePoolSize="16"
                          messageVersion="Soap11Addressing1"
                          encoding="utf-8" />
   </binding>

<!-- The WsProfileBinding, which can interop with
     anyone who speaks the WS-* protocols. It uses
     WS-Security at the SOAP layer to provide
     end-to-end security across intermediaries -->


   <binding configurationName="WsProfileBinding">
    <security algorithmSuite="Default"
              authenticationMode="SspiNegotiated"
              contextMode="Session"
              defaultProtectionLevel="EncryptAndSign"
              enableKeyDerivation="True"
              includeTimestamp="True"
              messageProtectionOrder="SignBeforeEncrypt"
              securityVersion="WSSecurityXXX2005" />
    <httpTransport hostnameComparisonMode="StrongWildcard"
                   manualAddressing="False"
                   maxMessageSize="65536"
                   authenticationScheme="Anonymous"
                   bypassProxyOnLocal="False"
                   mapAddressingHeadersToHttpHeaders="False"
                   realm=""
                   transferTimeout="00:10:00"
                   useSystemWebProxy="True" />
   <textMessageEncoding maxReadPoolSize="64"
                        maxWritePoolSize="16"
                        messageVersion="Default"
                        encoding="utf-8" />
   </binding>
 

<!-- The WsProfileDualHttpBinding, which layers a Reliable Messaging
     session on top of two HTTP channels, which lets you do duplex
     communication over HTTP. It's also secure by default. -->

   <binding configurationName="WsProfileDualHttpBinding">
    <reliableSession acknowledgementInterval="00:00:00.2000000"
                    advancedFlowControl="True"
                    bufferedMessagesQuota="32"
                    inactivityTimeout="00:10:00"
                    maxPendingChannels="128"
                    maxRetryCount="8"
                    ordered="True" />
    <security algorithmSuite="Default"
             authenticationMode="SspiNegotiated"
             contextMode="Session"
             defaultProtectionLevel="EncryptAndSign"
             enableKeyDerivation="True"
             includeTimestamp="True"
             messageProtectionOrder="SignBeforeEncrypt"
             securityVersion="WSSecurityXXX2005" />
    <compositeDuplex />
    <httpTransport hostnameComparisonMode="StrongWildcard"
                  manualAddressing="False"
                  maxMessageSize="65536"
                  authenticationScheme="Anonymous"
                  bypassProxyOnLocal="False"
                  mapAddressingHeadersToHttpHeaders="False"
                  realm=""
                  transferTimeout="00:10:00"
                  useSystemWebProxy="True" />
    <textMessageEncoding maxReadPoolSize="64"
                        maxWritePoolSize="16"
                        messageVersion="Default"
                        encoding="utf-8" />
   </binding>
 

<!-- The NetProfileTcpBinding, which is an Indigo/Indigo binding. -->

   <binding configurationName="NetProfileTcpBinding">
     <tcpTransport hostnameComparisonMode="StrongWildcard"
                 manualAddressing="False"
                 maxMessageSize="65536"
                 closeTimeout="00:00:01"
                 connectionBufferSize="65536"
                 connectionPoolGroupName="default"
                 maxBufferSize="65536"
                 maxInboundConnections="10"
                 maxOutputDelay="00:00:00.2000000"
                 maxPendingAccepts="1"
                 protectionLevel="EncryptAndSign"
                 transferMode="Buffered"
                 transferTimeout="00:10:00"
                 useIndigoListener="False"
                 IPv6ProtectionLevel="Default"
                 isKeepAliveEnabled="False"
                 listenBacklog="10"
                 securityMode="None" />
     <binaryMessageEncoding maxReadPoolSize="64" maxWritePoolSize="16" />
   </binding>

   <!-- The NetProfileDualTcpBinding, which is another Indigo/Indigo binding. -->

   <binding configurationName="NetProfileDualTcpBinding">
     <reliableSession acknowledgementInterval="00:00:00.2000000"
                    advancedFlowControl="True"
                    bufferedMessagesQuota="32"
                    inactivityTimeout="00:10:00"
                    maxPendingChannels="128"
                    maxRetryCount="8" ordered="True" />
     <security algorithmSuite="Default"
             authenticationMode="SspiNegotiated"
             contextMode="Session"
             defaultProtectionLevel="EncryptAndSign"
             enableKeyDerivation="True"
             includeTimestamp="True"
             messageProtectionOrder="SignBeforeEncrypt"
             securityVersion="WSSecurityXXX2005" />
     <compositeDuplex />
     <tcpTransport hostnameComparisonMode="StrongWildcard"
                 manualAddressing="False"
                 maxMessageSize="65536"
                 closeTimeout="00:00:01"
                 connectionBufferSize="65536"
                 connectionPoolGroupName="default"
                 maxBufferSize="65536"
                 maxInboundConnections="10"
                 maxOutputDelay="00:00:00.2000000"
                 maxPendingAccepts="1"
                 protectionLevel="EncryptAndSign"
                 transferMode="Buffered"
                 transferTimeout="00:10:00"
                 useIndigoListener="False"
                 IPv6ProtectionLevel="Default"
                 isKeepAliveEnabled="False"
                 listenBacklog="10"
                 securityMode="None" />
    <binaryMessageEncoding maxReadPoolSize="64" maxWritePoolSize="16" />
   </binding>

   <!-- The NetProfileNamedPipesBinding, which is an Indigo/Indigo binding
        for on-machine communication. -->

   <binding configurationName="NetProfileNamedPipesBinding">
     <namedPipeTransport hostnameComparisonMode="StrongWildcard"
                      manualAddressing="False"
                      maxMessageSize="65536"
                      closeTimeout="00:00:01"
                      connectionBufferSize="65536"
                      connectionPoolGroupName="default"
                      maxBufferSize="65536"
                      maxInboundConnections="10"
                      maxOutputDelay="00:00:00.2000000"
                      maxPendingAccepts="1"
                      protectionLevel="EncryptAndSign"
                      transferMode="Buffered"
                      transferTimeout="00:10:00"
                      useIndigoListener="False"
                      connectTimeout="00:00:02"
                      securityMode="Windows" />
     <binaryMessageEncoding maxReadPoolSize="64" maxWritePoolSize="16" />
  </binding>
</customBinding>

There's been a lot of work done to provide intelligent defaults for these values so that you won't have to change them in most cases. But I personally think it's reassuring to know that I have this level of configurability available to me if Iever need it.