2

So got an older WCF service / client I'm working on. Added a new (static) logging system to it, actually and now doing some load testing.

Getting some really annoying sporadic issues now - claiming "Secure channel cannot be opened because security negotiation with the remote endpoint has failed". I noticed I get a CommunicationException with a fault name of Sender and subcode of BadContextToken.

Weird thing is, I'll get 2-4 correct responses, then a flurry of these exceptions, then start getting good responses again.

This is my first real foray into WCF, and not loving it so far :)

Service web.config:

<system.serviceModel>
  <bindings>
    <wsHttpBinding>
      <security mode="Message">
        <message clientCredentialType="UserName" />
      </security>
    </wsHttpBinding>
  </bindings>
  <services>
    <service behaviorConfiguration="ServiceBehavior" name="MyNamespace.MyService">
      <endpoint address="" binding="wsHttpBinding" contract="MyNamespace.IMyService" bindingConfiguration="wsMessage">
        <identity>
          <dns value="localhost" />
        </identity>
      </endpoint>
    </service>
  </services>
  <behaviors>
    <serviceBehaviors>
      <behavior name="ServiceBehavior">
        <serviceMetadata httpGetEnabled="false" />
        <serviceCredentials>
          <serviceCertificate findValue="MyValue" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" />
          <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="MyNamespace.UserNamePassValidator, MyNamespace" />
        </serviceCredentials>
      </behavior>
    </serviceBehaviors>
  </behaviors>
</system.serviceModel>

And on the client side, the client is instantiated as such:

var binding = new WSHttpBinding();
binding.Name = "WSHttpBinding_IMyService";
binding.Security.Mode = SecurityMode.Message;
binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;

var client = new MyService(binding, "http://myserver:8080/myapp/service.svc");

var endpointIdentity = new DnsEndpointIdentity("MyValue"); // Match the certificate name used by the server

client.Endpoint.Address = new EndpointAddress(new Uri("http://myserver:8080/myapp/service.svc"), endpointIdentity, client.Endpoint.Address.Headers);

var creds = client.ClientCredentials;

creds.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None;
creds.UserName.UserName = "myuser";
creds.UserName.Password = "mypassword";

string retVal = client.SendRequest(); // SendRequest == one of the methods on my IMyService, returns a string.  This is also where I sporadically see my error when load testing.

I would appreciate any pointers to help me out with this WCF setup!

John
  • 921
  • 1
  • 9
  • 24
  • So after enabling WCF tracing and going through numerous hoops, our team agreed upon our solution - dump WCF for WebApi. We've had no more issues in the past year. – John Oct 26 '18 at 18:50

1 Answers1

0

These might be useful additions to your web.config:

<behaviors> 
    <serviceBehaviors> 
        <behavior name="CalculatorServiceBehavior">
            <serviceDebug includeExceptionDetailInFaults="False" /> 
            <serviceMetadata httpGetEnabled="True"/> 
            <serviceThrottling maxConcurrentCalls="20" maxConcurrentInstances="100"/> 
        </behavior>
     </serviceBehaviors>
</behaviors>

<binding name="basicHttp" allowCookies="true" maxReceivedMessageSize="1048576" maxBufferSize="1048576" maxBufferPoolSize="1048576">
    <readerQuotas maxDepth="32" maxArrayLength="1048576" maxStringContentLength="1048576"/>
</binding>

Usually this kind of "random" behaviour might depend on:

  1. Timeouts (probably not your case, since you'd get a different exception)
  2. Too many connections: if you client opens too many connections (and "forgets" to close them), you'll exceed the default allowed maximum (depending on context, it might be 10 connections). You can act on this if you alter your web.config, editing maxConcurrentCalls and maxConcurrentInstances
  3. Perhaps those errors are not random, but specific to some message; if so, that might be due to its size (i.e. it's too large): again, alter your web.config setting maxReceivedMessageSize, maxBufferSize, maxBufferPoolSize and readerQuotas

Of course you will get more info if you turn on WCF tracing.

Francesco B.
  • 2,729
  • 4
  • 25
  • 37