Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When setting up a WCF client and server, how synchronized does the config files must be?

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?

like image 608
Alex Avatar asked Feb 02 '11 20:02

Alex


People also ask

How to configure WCF service in Web config?

In This Section Starting with . NET Framework 4, WCF comes with a new default configuration model that simplifies WCF configuration requirements. If you do not provide any WCF configuration for a particular service, the runtime automatically configures your service with default endpoints, bindings, and behaviors.

What is binding configuration in WCF?

bindingConfiguration : A string that specifies the binding name of the binding to use when the endpoint is instantiated. The binding name must be in scope at the point the endpoint is defined. The default is an empty string.

How will you specify a method is available to access by client in WCF?

If your application must do more work while an operation completes, you should create an asynchronous method pair on the service contract interface that your WCF client implements. The easiest way to do this is to use the /async switch on the ServiceModel Metadata Utility Tool (Svcutil.exe).


1 Answers

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.

like image 149
marc_s Avatar answered Sep 20 '22 12:09

marc_s