Archive for the ‘WCF’ Category

Initial slow WCF request

Friday, October 23rd, 2009

SnailIf working with any of the HTTP Bindings you might experience that the first WCF request takes a long time to complete.

This is because the initial HTTP connection tries to get the proxy settings automatically. This is done by requesting the configuration via a HTTP GET http://wpad/wpad.dat. If proxy server automatic configuration is not configured, the request times out and the initial WCF can send the request directly to the destination address. This may add 30 seconds to the initial WCF request!

You can disable this behavior by specifying UseDefaultWebProxy = false on the binding.

You can read more about Web Proxy Auto-Discovery Protocol ( WPAD ) at Wikipedia.

This applies to basicHttpBinding, wsHttpBinding, wsDualHttpBinding, webHttpBinding, ws2007FederationHttpBinding, wsFederationHttpBinding, basicHttpContextBinding, wsHttpContextBinding and the new Azure ServiceBus bindings basicHttpRelayBinding, wsHttpRelayBinding, webHttpRelayBinding

How to view default values for a WCF binding

Thursday, April 23rd, 2009

… or create a custom binding from a build-in binding.
… or create an administrative XML-based configuration from an administrative programmatic configuration.

Below codes does all that:

// Specify the source binding
// - Programmatic binding
// - Administrative XML-based binding
// - Convert to custom binding

/* Programmatic binding */
var binding = new BasicHttpBinding();
binding.TransferMode = TransferMode.Streamed;
binding.MaxReceivedMessageSize = 10000;

/* Administrative XML-based binding */
// var binding = new BasicHttpBinding("basicHttp");

/* Convert to custom binding */
// var wsBinding = new WSHttpBinding("wsHttp");
// var binding = new CustomBinding(wsBinding);

string outputConfigFile = "out.config";

Configuration machineConfig = ConfigurationManager.OpenMachineConfiguration();

var fileMap = new ExeConfigurationFileMap();
fileMap.ExeConfigFilename = outputConfigFile;
fileMap.MachineConfigFilename = machineConfig.FilePath;

Configuration config = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
config.NamespaceDeclared = true;

var scg = new ServiceContractGenerator(config);

string sectionName, configName;
scg.GenerateBinding(binding, out sectionName, out configName);
config.Save();

The programmatic source binding will create a configuration file with all default values for the BasicHttpBinding except for TransferMode and MaxReceivedMessageSize attributes like so:

<basichttpbinding>
    <binding name="BasicHttpBinding"
             closeTimeout="00:01:00"
             openTimeout="00:01:00"
             receiveTimeout="00:10:00"
             sendTimeout="00:01:00"
             allowCookies="false"
             bypassProxyOnLocal="false"
             hostNameComparisonMode="StrongWildcard"
             maxBufferSize="65536"
             maxBufferPoolSize="524288"
             maxReceivedMessageSize="10000"
             messageEncoding="Text"
             textEncoding="utf-8"
             transferMode="Streamed"
             useDefaultWebProxy="true">
        <readerquotas maxDepth="32"
                      maxStringContentLength="8192"
                      maxArrayLength="16384"
                      maxBytesPerRead="4096"
                      maxNameTableCharCount="16384" />
        <security mode="None">
            <transport clientCredentialType="None"
                       proxyCredentialType="None"
                       realm="" />
            <message clientCredentialType="UserName"
                     algorithmSuite="Default" />
        </security>
    </binding>
</basichttpbinding>

I found this tip by Brian McNamara on the MSDN WCF forum.

Handcrafting the WCF client

Thursday, March 5th, 2009

Two years ago I wrote an article Building a Windows Communication Foundation client, describing three ways of creating WCF clients. I did not mention the fourth one, as I did not know at the time. Now I am older and wiser ;-)

The four ways of creating a WCF client are:

  1. Visual Studio’s “Add Service” reference
  2. Service Model Metadata Utility Tool (SvcUtil.exe) command line tool
  3. Dynamic proxy with ChannelFactory
  4. Handcrafting the WCF client

The last two options are only viable for WCF to WCF implementations where you either have control of both service and client or the service provider supplies a .Net assembly. Because both of them require the service contract aka the .Net interface marked with ServiceContractAttribute and OperationContractAttribute.

Anybody that has tried the “Add Service” reference in Visual Studio knows it is broken. First of all it generates an enormous amount of files, even for the simplest service contract.

Secondly it sometimes corrupts the state of the generated files, so you have to remove the reference and then add it again.. Just try to google it and you will find many frustrated developers. Do not use it!

The SvcUtil.exe is better and has a vast number of options. This is the preferred option for non .Net services or where the service contract interface is not available.

The dynamic proxy with ChannelFactory is useful, but be aware that the interface returned does not implement IDisposable, but the implementation does. See below:

var factory = new ChannelFactory<ihelloworldservice>("myEndPoint");

IHelloWorldService proxy = factory.CreateChannel();

using (proxy as IDisposable)
{
   MessageBox.Show(proxy.HelloWorld());
}

Finally the handcrafted version – the one I want to talk about. Writing the WCF client by hand is fairly easy – it requires the implementation to inherit from ClienBase and implementing the service contract interface. Below is first a simple service contract IHelloWorldService:

[ServiceContract(Namespace = "www.lybecker.com/blog/HelloWorldService")]
public interface IHelloWorldService
{
   [OperationContract]
   string HelloWorld();
}

Next the handcrafted WCF client with constructors and service contract interface implementation:

public class HelloWorldClient : ClientBase<ihelloworldservice>, IHelloWorldService
{
   public HelloWorldClient()
   { }

   public HelloWorldClient(string configurationName) : base(configurationName)
   { }

   public HelloWorldClient(Binding binding, EndpointAddress address) : base(binding, address)
   { }

   public string HelloWorld()
   {
      return Channel.HelloWorld();
   }
}

That’s it. :-)

Now you have full control of the WCF client implementation.

Download the sample application Hello World WCF clients including a handcrafted version

Serialization in .Net 3.5 SP1

Saturday, November 22nd, 2008

In .Net 3.5 SP1 it is now possible to serialize any object that has a default constructor without decorating it with [DataContract] or [Serializable].

Developers have these choices now when serializing objects:

  • Implicit serialization – requires public default constructor and only serialize public read/write fields
  • Use the [Serializable] attribute
  • Use [DataContract] and [DataMember] attributes
  • Implement the ISerializable interface

I must say, that I’m not keen on this new feature. I prefer explicit serialization to implicit serialization. I predict that implicit serialization of entire object graphs will cause performance problems for many .Net developers in the years to come. This could also be a good thing as I am a consultant  ;-)

Aaron Skonnard has a more detailed blog post about the new serialization features in .Net 3.5 SP1.

.Net debugger visualizers

Sunday, October 12th, 2008

The .Net framework 2.0 gave some great tools for debugging – they are a great help when writing code.

Some of these features are the DebuggerDisplay and DebuggerStepThrough attributes. I seldom use any of them, as I prefer to just overriding the ToString method instead of using the DebuggerDisplay attribute. This makes it easy to instrument the code too, as I can reuse the ToString method implementation for tracing.

Another feature is the ability to develop custom debugger visualizers. They enable smart developers to build their own. I find some really useful, especially the WCF visualizer. But there a many – check out this list of custom .Net debugger visualizers.

These small enhancements make it so easy to get an overview of the current state, instead of inspecting properties.

WCF certified

Sunday, April 20th, 2008

I just got word from Microsoft, that I passed the Microsoft Certified Technology Specialist: .NET Framework 3.5, Windows Communication Foundation Applications certification (70-503).

It was not easy, as the preparation guide was incomplete and I didn’t have time to properly prepare for the test. I took the beta exam in January, but had totally forgotten about it.

I am proud to be one of the first to pass this exam :-)

32-bit WCF memory allocation trouble

Tuesday, March 18th, 2008

With a 32 bit platform a process can only address 2 GB of memory by default on windows. For most applications this is not an issue. But today I really messed up – OOM (OutOfMemoryException) exceptions all over :-(

I added loads of test data to our 32 bit development servers and tried to run a development utility. It failed and failed and failed with OOM exceptions. The cause was actually quite simple as the application tried to allocate more than 500 MB of consecutive memory.

The utility is a console app and the search index is a WCF server and they communicate via TCP buffered binary format (netTCPBinding).

The console utility retrieved all the unique identifiers in the search index (based on Lucene.Net) to compare these with the records in the SQL Server, to see if everything is in sync. The number of unique identifiers where now in the millions, but that was not the root cause. The process consumed twice the memory, because I use buffered transfer mode instead of streamed.

Buffered transfer mode serializes everything before sending the message from the server to the client. So in effect our WCF server not only had the huge array of unique identifiers but also a serialized version. It never got the stage where it could send the message.

Moral of the story – use streamed transfer mode with large messages.

As this is a development utility, I sidestepped :-)

I enabled the 3GB switch allowing processes to allocate up to 3 GB of memory, and tried again. Same result: OOM.

I figured that the .Net might have a limitation and perhaps a switch to enable larger memory allocation. Apparently there is a small program called Microsoft COFF Binary File Editor (EDITBIN.EXE) that modifies Common Object File Format (COFF) binary files. This binary file editor can enable applications to address more than 2 GB of memory with the LARGEADDRESSAWARE option.

The steps to enable LARGEADDRESSAWARE for an application:

  1. Start Visual Studio Command Prompt or run VSVARS32.BAT (in the visual studio subdirectory: Common7\Tools) which in effect does the same things.
  2. Run editbin /LARGEADDRESSAWARE <yourApp>.exe

Tomorrow I will change the implementation to use streamed transfer mode. Promise :-)

simpsonsalwaysusestreamedtransfermode.gif

Microsoft product launch 2008

Saturday, February 16th, 2008

Microsoft product launch 2008

I am speaking at the launch of Windows Server 2008, Visual Studio 2008 and SQL Server 2008 in Denmark February 28th. It will be an online launch – meaning that you can watch in comfort of your personal development sphere :-D

As it is a Danish event and we Danes speak Danish – the event will be in Danish :-)

You can sign-up here.

WCF Sessions and Reliable Messaging

Monday, April 30th, 2007

There are a couple of ways to establish a session between client and service. The session is established by identifying clients via a unique identifier. The unique identifier is either conveyed by

  • the client credentials when WS-Security is utilized to established secure session
  • the TCP/IP socket connection when using an underlying connection-oriented protocol such as TCP
  • the WS-ReliableMessaging protocol token when requiring message ordering and message delivery assurance for transport protocols.

Read more about how WS-Reliable Messaging protocol in my article “How does Reliable Messaging work?

Enabling sessions are all done in the configuration file. Some bindings are sessionful by default like the tcpBinding and wsHttpBinding.

I continue with Hello World WCF code sample from my earlier articles: “Building a Windows Communication Foundation client” and “A simple Windows Communication Foundation Web Service”. You can download the source code from here: Hello World WCF with clients.

Just by changing the binding in the code sample configuration to wsHttpBinding in the service and the clients, you get secure sessions; wsHttpBinding is by default secured with message security. The secure session context is established with the WS-SecureConversation protocol.

In the service type implementation it is possible to retrieve the session identifier via the OperationContext.Current.SessionId.

If you want un-secure reliable ordered messages with sessions, then change the behavior of the wsHttpBinding by configuring the binding like below. The configuration shown is for the service, but the changes (in bold) are exactly the same as required in the clients’ configuration files.

< ?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system .serviceModel>
    <behaviors>
      <servicebehaviors>
        <behavior name="myBehavior">
          <servicemetadata httpGetEnabled="true"
                           httpGetUrl="http://localhost:8080/HelloWorldService" />
        </behavior>
      </servicebehaviors>
    </behaviors>
    <bindings>
      <wshttpbinding>
        <binding name="reliableBinding">
          <reliablesession enabled="true" ordered="true"/>
          <security mode="None" />
        </binding>
      </wshttpbinding>
    </bindings>
    <services>
      <service name="HelloWorldService"
               behaviorConfiguration="myBehavior">
        <endpoint address="http://localhost:8080/HelloWorldService"
                  binding="wsHttpBinding"
                  bindingConfiguration="reliableBinding"
                  contract="IHelloWorldService" />
      </service>
    </services>
  </system>
</configuration>

Now the session identifiers are conveyed by the WS-Reliable Messaging protocol (linie 13-18). It is possible to use secure and reliable messages, but security is disabled to prove the point of WS-Reliable Messaging can be used to establish sessions.

If the implementation of your service requires sessions, decorate the service contract with the SessionMode.Required – this will demand that every endpoint bindings exposing the service support sessions. The possible values of the SessionMode enum are Required, Allowed and NotAllowed where Allowed is default.

[ServiceContract(SessionMode=SessionMode.Required)]
public interface IHelloWorldService
{
    [OperationContract]
    string HelloWorld();
}

If guaranteed ordering of messages is assumed by the implementation and therefore required for dependable behavior of the service, then decorate the service contract with the DeliveryRequirements attribute with the parameter RequireOrderedDelivery set to true.

[ServiceContract(SessionMode=SessionMode.Required)]
[DeliveryRequirements(RequireOrderedDelivery=true)]
public interface IHelloWorldService
{
    [OperationContract]
    string HelloWorld();
}

If the configuration of an endpoint does not fulfill the requirements, the host throws an exception detailing the missing requirements.

When to use the sessions
Sessions in WCF does not deliver the same functionality as in ASP.Net or ASMX based Web Services. For instance the HttpSessionState store is not available, not even if the WCF service is hosted in the IIS. WCF sessions are similar to Remoting sessions and are only for service instancing.

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
public class HelloWorldService : IHelloWorldService
{
    public string HelloWorld()
    {
        Console.WriteLine("Invoked by client with session ID {0}",
            OperationContext.Current.SessionId);

        return "Hello World";
    }
}

To control the instancing of the service type objects, decorate the service type with the ServiceBehavior attribute and specify the InstanceContextMode enum as in the above code.

The InstanceContextMode values are:

  • PerCall – A new InstanceContext object is created prior to and recycled subsequent to each call. If the channel does not create a session this value behaves as if it were PerCall.
  • PerSession – A new InstanceContext object is created for each session.
  • Single – Only one instance of the service type object is used for all incoming calls and is not recycled subsequent to the calls. If a service type object does not exist, one is created.

Download the sample code with reliable messaging here (Hello World WCF Reliable Messaging) and read more about WCF sessions here.

Great conference

Wednesday, March 14th, 2007

The Miracle SQL Server Open World conference was a great success. There were lots of informative sessions and great networking. I spoke to a lot of interesting people from all over the world including Microsoft SQL Server guys from Redmond and one as far away as from Brisbane, Australia. Bear in mind that this conference is held in the countryside, far away from anything, two hours drive from Copenhagen, Denmark.

I promised the attendances’ at my session “Transactions with Windows Communication Foundation” to post a guide to setup the Distributed Transaction Coordinator (DTC) for WCF. I have posted two guides:

Hope to see all of these interesting people again at next year’s Miracle SQL Server Open World conference.