15

Most of the WCF examples out there show you how to configure WCF client and server. Now, what happens if you differ the configuration slightly between them? I mean, who has the final word?

Let's take this client configuration for example:

<configuration>
<system.serviceModel>
    <bindings>
        <wsHttpBinding>
            <binding name="WSHttpBinding_ISampleService" closeTimeout="00:01:00"
                openTimeout="00:01:00" receiveTimeout="00:01:00" sendTimeout="00:01:00"
                bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
                maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
                messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
                allowCookies="false">
                <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                    maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                <reliableSession ordered="true" inactivityTimeout="00:10:00"
                    enabled="false" />
                <security mode="Message">
                    <transport clientCredentialType="None" proxyCredentialType="None"
                        realm="" />
                    <message clientCredentialType="Windows" negotiateServiceCredential="true"
                        algorithmSuite="Default" establishSecurityContext="true" />
                </security>
            </binding>
        </wsHttpBinding>
    </bindings>
    <client>
        <endpoint address="http://localhost:8080/SampleService" binding="wsHttpBinding"
            bindingConfiguration="WSHttpBinding_ISampleService" contract="ISampleService"
            name="WSHttpBinding_ISampleService">
        </endpoint>
    </client>
</system.serviceModel>

Usually the server side will have the exact same binding configured on its exposed server.

But what happens now if on the server side is defined with openTimeout = 00:00:30. What will be the timeout? Who wins? I do the same question for all other parameters.

The whole thing seems a big mess, how can you tell, for each element of the configuration (binding, client, service, behavior, etc.) and all their details, which parameters is required and in which side (client or server)?

It seems you could define the entire binding with all timeout parameters on the server side and on the client side simply put the minimum required configuration so all parameters from the server are accepted. But now, what are the minimum required parameters on the client considering the server has a more in depth configuration?

What are the best practice when configuring client and server using WCF regarding parameters for each element of the configuration: bindings, services, client/endpoint and behavior?

When conflicting parameters are defined between client and server how WCF handles it?

Alex
  • 1,366
  • 19
  • 22
  • 1
    What I'm looking for here as an answer is something like: most of the time the server configuration is the father of all configurations and some attributes can be changed on the client side. Or something like that. If you can help me change the question text to make it clear I appreciate it. – Alex Feb 02 '11 at 20:23
  • I'm playing with some different configurations and for example the maxReceivedMessageSize of the httpTransport element seems to work like this: you can define it on the server and the client but if you don't define in one side than the default value (65k) is used. How does that help? Unless I know how the server has been configured and I copy the same values on the client I can't get the behavior I want. This trial and error drives me crazy! I wish I could write this question as a one simple statement that could solve my problems with WCF configuration. – Alex Feb 02 '11 at 20:51
  • See my latest update - and yes, at times, WCF configuration is indeed trial & error - learn from it, next time around you'll know and over time, you'll build up your WCF experience. It's a big beast - don't attempt to know it all from the get go - you won't.... – marc_s Feb 02 '11 at 21:56
  • ok I have not read the answers yet but I just wanted to say "dang good question!" – hal9000 Aug 31 '11 at 15:17

2 Answers2

15

In order to address your request in your last comment to my previous answer, I tried to come up with my approach to how I would create (and modify) server- and client-side config's for any given service. This is based on both theory I read (books, blogs), things I've learned in Juval Lowy's WCF Master Class, and quite a bit of practical experience with several large service implementation projects - this isn't available in one single place, on the web or in a book.... so here it goes:

I would start basically from scratch. Think about your service first:

  • what address does your service live at?
  • what binding(s) do you want to support?

Simplest scenario: single service, single endpoint, basicHttpBinding, all defaults

Service config:

<system.serviceModel>
   <services>
      <service name="YourNamespace.YourServiceClass">
         <endpoint name="Default"
             address="http://YourServer/SomeVirtualDirectory/YourService.svc"
             binding="basicHttpBinding"
             contract="YourNamespace.IYourServiceContract" />
      </service>
   </services>
</system.serviceModel>

Corresponding client config:

<system.serviceModel>
   <client name="Default">
      <endpoint name="Default"
          address="http://YourServer/SomeVirtualDirectory/YourService.svc"
          binding="basicHttpBinding"
          contract="YourClientProxyNamespace.IYourServiceContract" />
   </client>
</system.serviceModel>

Then only ever change something if you really must! And most of all: NEVER EVER let Visual Studio (Add Service Reference) or svcutil.exe screw up your config! Protect it like the apple of your eye!

Then: if e.g. your data transfer takes more time than the default timeout of 1 minute allows, change that one single setting on both the service side and the client side. Do this by defining a custom binding configuration and referencing that from your endpoints - but change only that - not more! Leave everything else as is, with default values. Don't ever change anything unless you absolutely must (and know what you're doing, and why you're doing it).

Mind you: the sendTimeout on the client (time allowed until the whole message has been sent) will correspond to the receiveTimeout on the server - the time allowed for the whole message to come in (see this excellent blog post and this MSDN forum thread for more information)

Service config:

 <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="ExtendedTimeout"
                 receiveTimeout="00:05:00" />
      </basicHttpBinding>
    </bindings>
    <services>
      <service name="YourNamespace.YourServiceClass">
        <endpoint name="Default"
            address="http://YourServer/SomeVirtualDirectory/YourService.svc"
            binding="basicHttpBinding"
            bindingConfiguration="ExtendedTimeout"
            contract="YourNamespace.IYourServiceContract" />
      </service>
    </services>
  </system.serviceModel>

Corresponding client config:

<system.serviceModel>
   <bindings>
      <basicHttpBinding>
         <binding name="ExtendedTimeout"
                  sendTimeout="00:05:00" />
      </basicHttpBinding>
   </bindings>
   <client name="Default">
      <endpoint name="Default"
          address="http://YourServer/SomeVirtualDirectory/YourService.svc"
          binding="basicHttpBinding"
          bindingConfiguration="ExtendedTimeout"
          contract="YourClientProxyNamespace.IYourServiceContract" />
   </client>
</system.serviceModel>

As you need other changes, like multiple endpoints on the service side, or local settings like bypassProxyOnLocal - adapt your config, do it carefully, step by step, manually, and consider your config an extremely essential part of your whole service - take care of it, put it in version control etc.

Community
  • 1
  • 1
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
  • 1
    That's exactly what I was looking for!!! I 'knew' that the configuration tip was spread all over the place and that is exactly what I was looking for: someone more experienced with WCF that had some general guidelines on how to configure client/server. That kind of insight about sendTimeout is translated to receiveTimeout is essential and MSDN is lacking an overall documentation on those kind of perks. I will give it a day or two just to allow people to contribute with other answers but sounds like a winner to me. Thanks a lot @marc_s ! – Alex Feb 03 '11 at 14:26
  • `` -- adding namespace to service name makes the service fail. Removing the namespace allows service to start. – greenoldman Jan 27 '13 at 22:17
2

If a given timeout is about the same thing in the end, on the client and the server, and the two values don't match, the shorter timeout "wins" - no matter whether it's defined on the server or the client.

Most other things like addresses, bindings etc. must match - otherwise, no communication will be possible...

The benefit of the server setup is that you can define multiple endpoints for a single service, with different options and bindings - and the client can then "pick and choose" which endpoint to connect to.

But once one service endpoint has been chosen for your connection, the settings like bindings, protocols, security, reliability and so forth must match exactly.

Also: the default config that the Visual Studio Add Service Reference or the svcutil.exe command line tools generate are both catastrophically bad - they contain way too many settings that all reflect the default values, which make it really hard to know what's really needed and what is not.

In that respect, I'd recommend watching the DotNet Rocks TV Show #122: Miguel Castro on Extreme WCF in which Miguel nicely shows just how easy it really is to create those configs manually, and then you completely understand what the heck you're doing! Highly recommended!

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
  • That makes sense, but what about other parameters? bypassProxyOnLocal? transactionFlow? allowCookies? Let's say the default of "allowCookies" is true. If I set it to false on the server and then on the client I don't say anything, what will it be? true (the default) or false (the server config)? – Alex Feb 02 '11 at 20:20
  • @Alex: AllowCookies or BypassProxyOnLocal would be client-side only settings, as far as I know and understand. The server might set something, but those wouldn't be relevant - those only affect the client (some settings aren't even taken from the server side, when you do Add Service Reference). TransactionFlow is another one of those that **must** match between the client and the server - otherwise, things won't work – marc_s Feb 02 '11 at 20:22
  • @marc_s Ok, exactly, is there any documentation that explains the parameters by groups? Like client-only, server-mandatory, etc.? It's really though to keep doing this guessing game all the time. I don't know all the parameters by heart. You see where I'm going? – Alex Feb 02 '11 at 20:25
  • @Alex: the **ultimate** reference probably is the MSDN docs on the [ config section](http://msdn.microsoft.com/en-us/library/ms731354.aspx) (and its children). Looking at this, it seems to me that the "AllowCookies" setting does have an impact on the server side, too, if you interface with old ASMX services... – marc_s Feb 02 '11 at 20:26
  • @Alex: and that's one of the points Miguel also makes in his webcast: you don't have to know all the properties and provide values for them; start with those you really need - address, binding, contract, maybe timeouts and leave the rest to defaults (which are typically quite sensible) - and build from there, once you see a need for something more – marc_s Feb 02 '11 at 20:29
  • @marc_s I agree Marc, building from scratch seems more reasonable. Although I still don't know how a proper setup would look like. When configuring WCF client and server should I put most of the timeouts on the server and don't put them on the client unless I specifically need to change one of them? Can we build an answer that gives us a general rule of "what a good (as in best practice) WCF client and server configuration would be"? Can we do that? – Alex Feb 02 '11 at 20:40