PMC
PMC

Reputation: 4756

WCF performance transferring List of objects using wsHttpBinding

I am trying to reduce the time taken to send a list of DTO objects over the internet using wsHttpBinding. Security is TransportWithMessageCredential with an X509 certificate. The time is about 2.5s for 500 objects in a list, using basicHttpBinding with no security only saves a few milliseconds.

Changing messageEncoding to Mtom seemed to slow it down further. I had added tracing and viewed files using svcTraceViewer and the longest time shown was after the message was sent there was an activity boundary then "The server security session received a close message from the client" which was 1.5 seconds, the transfer seemed only to take 400ms.

I have added the following Context and Concurrency attributes to the service class

 [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession,ConcurrencyMode=ConcurrencyMode.Multiple)]

In the DTO classes, I have added name to the data member to reduce time de-serializing

  [Serializable]
[DataContract(Name="Sample")]
public class Sample
{
    [DataMember(Name="Id")]
    public int Id { get; set; }

In the service Web.Config file the behavior is

  <behaviors>
  <serviceBehaviors>
    <behavior name="MyBehavior">
      <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
      <serviceMetadata httpsGetEnabled="true" />
      <serviceDebug includeExceptionDetailInFaults="false" />
      <serviceThrottling maxConcurrentCalls="300" maxConcurrentSessions="5000"  maxConcurrentInstances="300" />
    </behavior>
    <behavior>
      <serviceMetadata httpsGetEnabled="true" />
      <serviceDebug includeExceptionDetailInFaults="false" />
    </behavior>
  </serviceBehaviors>
</behaviors>

Client Web.Config has binding of

   <wsHttpBinding>
    <binding name="MyEndpoint" 
             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="2147483647"
             messageEncoding="Mtom" 
             textEncoding="utf-8"
             useDefaultWebProxy="false"
             allowCookies="false"  >
      <readerQuotas 
            maxDepth="2147483647" 
            maxStringContentLength="2147483647" 
            maxArrayLength="2147483647"
            maxBytesPerRead="2147483647" 
            maxNameTableCharCount="2147483647" />
      <reliableSession 
            ordered="true" 
            inactivityTimeout="00:10:00"
            enabled="false" />
      <security mode="TransportWithMessageCredential">
        <transport 
            clientCredentialType="None"  />
        <message 
            clientCredentialType="Certificate"  />
      </security>
    </binding>
  </wsHttpBinding>

and behavior setting

 <behavior name="MyBehavior">
              <dataContractSerializer maxItemsInObjectGraph="2147483647" />
              <clientCredentials>
                  <clientCertificate findValue="xxxxxxx" storeLocation="LocalMachine" x509FindType="FindByThumbprint" />
              </clientCredentials>
          </behavior>

Is there any suggestions how to get this to be fast and scalable?

SOLUTION It turns out that gzip wasn't actually installed in IIS as we had assumed. I will definitely be testing Marc Gravell's protobuf-net for production, however gzip solved the immediate problem.

Upvotes: 0

Views: 983

Answers (3)

Kristoffer
Kristoffer

Reputation: 834

You could pobably benefit a lot from using GZip compression.

Upvotes: 2

Marc Gravell
Marc Gravell

Reputation: 1062540

Bandwidth time and serialization/deserialization time may be a factor here. Also, transport-security time will be roughly related to bandwidth size. I suggest one thing you could look at here would be reducing the bandwidth time. Disclaimer: I'm the author (but I'm not selling anything; 'tis all free/OSS) - but: protobuf-net uses a much denser data format than DataContractSerializer, and has hooks to attach to WCF to swap the serializer. When using this you would ideally want MTOM enabled, as it is binary. This can be done either explicitly or via configuration. Note that it works simplest if the two ends are using assembly sharing; if you are using "mex" to generate the client half, some extra steps may be involved.

Upvotes: 1

Steven Muhr
Steven Muhr

Reputation: 3379

Have a look to PROTOBUF: Protocols Buffers Test

You also have a .net version : protobuf-net

Upvotes: 1

Related Questions