{"id":123,"date":"2006-06-06T17:41:52","date_gmt":"2006-06-07T00:41:52","guid":{"rendered":"http:\/\/kennyw.com\/indigo\/123"},"modified":"2006-06-06T17:41:52","modified_gmt":"2006-06-07T00:41:52","slug":"building-a-composite-transport","status":"publish","type":"post","link":"https:\/\/kennyw.com\/?p=123","title":{"rendered":"Building a &quot;Composite&quot; Transport"},"content":{"rendered":"<p>I&#8217;ve often written about how to write custom channels; transports in particular. In all of the examples I&#8217;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, <a href=\"http:\/\/msdn.microsoft.com\/ws\/2004\/10\/ws-discovery\/\">WS-Discovery<\/a> 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.<\/p>\n<p>Constructing a binding for this scenario requires three pieces:<\/p>\n<ol>\n<li>An outgoing transport<\/li>\n<li>An incoming transport<\/li>\n<li>A correlation mechanism to tie the request to the response<\/li>\n<\/ol>\n<p>For the transports, you need a <code class=\"classname\">BindingElement<\/code> that returns the outgoing transport from <code>BuildChannelFactory<\/code> and the incoming transport from <code>BuildChannelListener<\/code>.  One way of doing this is with a <strong>CompositeTransportBindingElement<\/strong>.  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.<\/p>\n<p>For correlation, if you add <code class=\"classname\">CompositeDuplexBindingElement<\/code> 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 :))<\/p>\n<p>The relevant pieces of CompositeTransportBindingElement (<a href=\" \/wp-content\/indigo\/CompositeTransportBindingElement.cs\">posted here<\/a>) are:<\/p>\n<pre><code class=\"keyword\">class<\/code> <code>CompositeTransportBindingElement\n        : <\/code><code class=\"classname\">TransportBindingElement<\/code><code>\n{\n    <\/code><code class=\"classname\">Binding<\/code><code> channelBinding;\n    <\/code><code class=\"classname\">Binding<\/code><code> listenerBinding;\n\n<\/code><code class=\"keyword\">    public<\/code> <code>CompositeTransportBindingElement(\n        Binding channelBinding,\n        Binding listenerBinding)\n    {\n        this.channelBinding = channelBinding;\n        this.listenerBinding = listenerBinding;\n    }<\/code>\n\n<code class=\"keyword\">    public override<\/code> <code>IChannelFactory&lt;TChannel&gt;\n             BuildChannelFactory&lt;TChannel&gt;(<\/code><code class=\"classname\">BindingContext<\/code><code> context)\n    {<\/code>\n        <code class=\"keyword\">return<\/code><code> channelBinding.BuildChannelFactory&lt;TChannel&gt;(\n            context.BindingParameters);\n    }<\/code>\n\n<code class=\"keyword\">    public override<\/code> <code>IChannelListener&lt;TChannel&gt;\n            BuildChannelListener&lt;TChannel&gt;(<\/code><code class=\"classname\">BindingContext<\/code> <code>context)\n    {<\/code>\n        <code class=\"keyword\">return<\/code><code> listenerBinding.BuildChannelListener&lt;TChannel&gt;(\n            context.ListenUriBaseAddress,\n            context.ListenUriRelativeAddress,\n            context.ListenUriMode,\n            context.BindingParameters);\n    }\n}<\/code>\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>I&#8217;ve often written about how to write custom channels; transports in particular. In all of the examples I&#8217;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 [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[11],"tags":[],"class_list":["post-123","post","type-post","status-publish","format-standard","hentry","category-indigo"],"_links":{"self":[{"href":"https:\/\/kennyw.com\/index.php?rest_route=\/wp\/v2\/posts\/123","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/kennyw.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/kennyw.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/kennyw.com\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/kennyw.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=123"}],"version-history":[{"count":0,"href":"https:\/\/kennyw.com\/index.php?rest_route=\/wp\/v2\/posts\/123\/revisions"}],"wp:attachment":[{"href":"https:\/\/kennyw.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=123"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/kennyw.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=123"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/kennyw.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=123"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}