It is fairly common knowledge that the NetTcpBinding in WCF provides the most efficient communication between a client and service that exist on separate machines. The default binary encoding and TCP transport is difficult to beat in terms of transfer speed.
However, TCP is sometimes not an option due to firewalls or other prohibiting factors. In those situations, HTTP is typically the transport of choice. Unfortunately, the default HTTP bindings in WCF do not allow binary encoding. With the default bindings (BasicHttpBinding, WsHttpBinding, and WsDualHttpBinding), you are limited to text or MTOM encoding.
If the client and service are both running on the WCF platform, it is still possible to leverage the benefit of binary encoding. The ability to do so requires a custom binding. There are two ways to create a custom binding:
- Build a custom binding class by inheriting from the Binding class.
- Specify a custom binding in the WCF configuration
The first option is useful when you want to limit the options of the binding. For example, you only want to allow the use of certain encoders or require reliable sessions. The custom binding implementation validates only the allowed options are used. It can also be compiled into an assembly for easy distribution.
The second option is achieved by simply manipulating the service configuration. However, there is no way to enforce a specific range of configuration values. Anyone with access can modify the configuration to their liking. Deployment can also become an issue since the client must have a corresponding configuration in order to construct a matching communication stack. This can be handled more gracefully when a proxy and configuration file are automatically generated via SvcUtil.exe. However, it requires the client having access to the metadata exchange.
There is a good example of implementing a custom binding for binary encoding with HTTP on the WCF community site. It can be found here. Although it was based on a CTP version of WCF, the concept is still applicable to the official release.
Below is an example of how to enable a custom binding via the service configuration file:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<customBinding>
<binding name="NetHttpBinding">
<reliableSession />
<compositeDuplex />
<oneWay />
<binaryMessageEncoding />
<httpTransport />
</binding>
</customBinding>
</bindings>
<services>
<service name="MyService">
<endpoint
address="http://localhost:8001/myService/"
binding="customBinding"
bindingConfiguration="NetHttpBinding"
contract="MyServiceContract"
name="HttpBinding" />
</service>
</services>
</system.serviceModel>
</configuration>
The custom binding is defined within the customBinding element of the configuration. It should be emphasized the order of the binding elements within the custom binding are important. The order in which they appear within the binding is the order in which they are placed within the communication stack.
Within the service element, an endpoint is defined that used the custom binding. In order for a client to consume the service via this endpoint, it must have a corresponding configuration to construct a channel stack that uses the custom binding.