Sunday, April 11, 2010

WCF Callback aka Duplex


In the code sample a IPC (inter-process communication) named pipe is used to communicate between client and service using a callback.  Named pipes are recommended for use when communication is only between processes on the same machine.  Here is a chart outlining selection of a binding from Soledad Pano's blog sourced from Juval Lowry's book Programming WCF Services.

There is only really two things to get right with WCF. One is configuration, and the other is serialisation of data.  Serialisation is a big topic on its own, but in my experience its best to make use of DTOs, and avoid the use of generics in DTOs.  DTO's are essentially specific objects created to transfer data from one place to another.  They only contain data properties.

Here is a sample WCF Server app.config. 

    1 <?xml version="1.0" encoding="utf-8" ?>
    2 <configuration>
    3   <system.web>
    4     <compilation debug="true" />
    5   </system.web>
    7   <system.serviceModel>
    8     <services>
    9       <service
   10           name="WCFCallbacks.MessageService"
   11           behaviorConfiguration="WCFCallbacks.MessageBehavior">
   12         <host>
   13           <baseAddresses>
   14             <add baseAddress = "net.pipe://myservice" />
   15           </baseAddresses>
   16         </host>
   17         <endpoint
   18             address =""
   19             binding="netNamedPipeBinding"
   20             contract="WCFCallbacks.IMessage">
   21           <identity>
   22             <dns value="localhost"/>
   23           </identity>
   24         </endpoint>
   25         <endpoint
   26             address="http://localhost:8001/myservice"
   27             binding="mexHttpBinding"
   28             contract="IMetadataExchange"/>
   29       </service>
   30     </services>
   32     <behaviors>
   33       <serviceBehaviors>
   34         <behavior name="WCFCallbacks.MessageBehavior">
   35           <serviceMetadata httpGetEnabled="False"/>
   36           <serviceDebug includeExceptionDetailInFaults="True" />
   37         </behavior>
   38       </serviceBehaviors>
   39     </behaviors>
   40   </system.serviceModel>
   41 </configuration>

Config settings can also be set using the SvcConfigEditor.exe from within Visual Studio.

Here's a sample Client Config file:

    1 <?xml version="1.0" encoding="utf-8" ?>
    2 <configuration>
    4     <system.serviceModel>
    5         <bindings>
    6             <netNamedPipeBinding>
    7                 <binding name="NetNamedPipeBinding_IMessage" closeTimeout="00:01:00"
    8                     openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
    9                     transactionFlow="false" transferMode="Buffered"transactionProtocol="OleTransactions"
   10                     hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="524288"
   11                     maxBufferSize="65536" maxConnections="10" maxReceivedMessageSize="65536">
   12                     <readerQuotas maxDepth="32" maxStringContentLength="8192"maxArrayLength="16384"
   13                         maxBytesPerRead="4096" maxNameTableCharCount="16384" />
   14                     <security mode="Transport">
   15                         <transport protectionLevel="EncryptAndSign" />
   16                     </security>
   17                 </binding>
   18             </netNamedPipeBinding>
   19         </bindings>
   20         <client>
   21             <endpoint address="net.pipe://myservice/" binding="netNamedPipeBinding"
   22                 bindingConfiguration="NetNamedPipeBinding_IMessage"contract="MessageService.IMessage"
   23                 name="NetNamedPipeBinding_IMessage">
   24                 <identity>
   25                     <dns value="localhost" />
   26                 </identity>
   27             </endpoint>
   28         </client>
   29     </system.serviceModel>
   30 </configuration>

It is recommended to only use config files to configure a service that needs to be changed at runtime. If for example the service does not need designed to be changed at runtime, rather programmatically set the service properties.

Options include:
  • IIS
    The advantage of using IIS, is management of service life cycle, and starting up on first call etc.  Only Http(s) bindings can be used.
  • WAS
    The Windows Activation Service can host any WCF service using any binding and still has all the advantages of IIS's life time management.  The WAS feature is only available in Vista and above.
  • Self Hosting using the ServiceHost class.
    This gives the developer the ability to host within a Windows service, console, or any other application.  The ServiceHost class is not available in the Client framework; ie not available in Silverlight.

Consuming a service client side there may be more limitations based on client environment.  If hosting within a Silverlight application, only Http(s) bindings are available, and wsDualHttpBinding is unavailable meaning callbacks are not possible.

No comments:

Post a Comment