Reputation: 4756
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
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
Reputation: 3379
Have a look to PROTOBUF: Protocols Buffers Test
You also have a .net version : protobuf-net
Upvotes: 1