views:

77

answers:

0

I haven't deployed behind a load balancer before. My customer has a WCF service built and tested on servers using a service model configuration that is relatively straightforward. It provides a service to return an image of a map for another application. To get the map, it calls other services.

The service was built in Visual Studio 2010 targeting the 3.5 framework. The customer is using IIS 7.5 and an F5 load balancer. When moving to the production server, the Web.config was changed to add the load balancer behavior and specify the endpoint to show the physical and logical address of the service:

        <services>
      <service behaviorConfiguration="Service.Service1Behavior" name="StaticMapImageService.Data.MapImageService">
        <endpoint 
                address="https://gis.customer.com/StaticMapImage/Service/StaticMapImageService.svc" 
                binding="basicHttpBinding" 
                bindingNamespace="http://customer.com"
                contract="StaticMapImageService.Data.IMapImageService"
                listenUri="http://hq-gis01.customer.net/StaticMapImage/Service/StaticMapImageService.svc"
                behaviorConfiguration="SSLLoadBalancerBehavior">
        </endpoint>
        <endpoint 
                address="mex" 
                binding="mexHttpBinding" 
                bindingNamespace="http://werner.com"
                contract="IMetadataExchange"/>
      </service>
    </services>

There is no entry for this service in the system.servicemodel/bindings section. The other services are configured in the bindings and client sections:

        <bindings>
      <basicHttpBinding>
        <binding name="BasicHttpBinding_IAddressVerificationService"
            closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00"
            sendTimeout="00:01:00" allowCookies="false" bypassProxyOnLocal="false"
            hostNameComparisonMode="StrongWildcard" maxBufferSize="999999999"
            maxBufferPoolSize="524288" maxReceivedMessageSize="999999999"
            messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
            useDefaultWebProxy="true">
          <readerQuotas maxDepth="32" maxStringContentLength="999999999" maxArrayLength="16384"
              maxBytesPerRead="4096" maxNameTableCharCount="16384" />
          <security mode="None">
            <transport clientCredentialType="None" proxyCredentialType="None"
                realm="" />
            <message clientCredentialType="UserName" algorithmSuite="Default" />
          </security>
        </binding>
        <binding name="BasicHttpBinding_IGeocoderService" closeTimeout="00:01:00"
            openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
            allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
            maxBufferSize="999999999" maxBufferPoolSize="524288" maxReceivedMessageSize="999999999"
            messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
            useDefaultWebProxy="true">
          <readerQuotas maxDepth="32" maxStringContentLength="999999999" maxArrayLength="16384"
              maxBytesPerRead="4096" maxNameTableCharCount="16384" />
          <security mode="None">
            <transport clientCredentialType="None" proxyCredentialType="None"
                realm="" />
            <message clientCredentialType="UserName" algorithmSuite="Default" />
          </security>
        </binding>
        <binding name="PCMilerSoap" closeTimeout="00:01:00" openTimeout="00:01:00"
            receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false"
            bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
            maxBufferSize="999999999" maxBufferPoolSize="524288" maxReceivedMessageSize="999999999"
            messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
            useDefaultWebProxy="true">
          <readerQuotas maxDepth="32" maxStringContentLength="999999999" maxArrayLength="16384"
              maxBytesPerRead="4096" maxNameTableCharCount="16384" />
          <security mode="None">
            <transport clientCredentialType="None" proxyCredentialType="None"
                realm="" />
            <message clientCredentialType="UserName" algorithmSuite="Default" />
          </security>
        </binding>
      </basicHttpBinding>
      <wsHttpBinding>
        <binding name="WSHttpBinding_IGeocoderService" closeTimeout="00:01:00"
            openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
            bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
            maxBufferPoolSize="524288" maxReceivedMessageSize="999999999"
            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="Windows" proxyCredentialType="None"
                realm="" />
            <message clientCredentialType="Windows" negotiateServiceCredential="true"
                algorithmSuite="Default" establishSecurityContext="true" />
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <client>
      <endpoint address="https://gis.customer.com/AddressVerification/Service/AddressVerificationService.svc"
          binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IAddressVerificationService"
          contract="AddressVerificationService.IAddressVerificationService"
          name="BasicHttpBinding_IAddressVerificationService" />
      <endpoint address="https://gis.customer.com/Geocoder/Service/GeocoderService.svc/ws"
          binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IGeocoderService"
          contract="GeocoderService.IGeocoderService" name="WSHttpBinding_IGeocoderService">
        <identity>
          <dns value="localhost" />
        </identity>
      </endpoint>
      <endpoint address="https://gis.customer.com/Geocoder/Service/GeocoderService.svc/soap"
          binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IGeocoderService"
          contract="GeocoderService.IGeocoderService" name="BasicHttpBinding_IGeocoderService" />
      <endpoint address="http://hq-miler02.customer.net/MultiMiler/ALKWS/PCMiler.asmx"
          binding="basicHttpBinding" bindingConfiguration="PCMilerSoap"
          contract="PCMiler.PCMilerSoap" name="PCMilerSoap" />
    </client>

There was a problem when the service was deployed to a server behind the load balancer. When I try to call the service from WCFStorm or WebServiceStudio I get the message "The provided URI scheme 'https' is invalid; expected 'http'.

The endpoints for the service itself look right to me. However in the development and testing versions of the config, the client section uses http instead of http, while on the production servers it uses the load balancer's https address.

This seems like it should be obvious, but we're missing it. Can anybody give us a clue?