Otiel
Otiel

Reputation: 18743

Message oversized on WCF communication

I have a windows service and a winform application that communicate between each other using WCF through TCP.

I sometimes have to exchange huge data and I encountered a CommunicationException on the client. Now I have trouble finding which property to change and where (on the server side or the client side?).

The problem occurs when the server is returning a value to the client that is a 2-uple (my own implementation) of two arrays of doubles: Tuple<Double[], Double[]> (both arrays have always the same length).
I have noticed that there is no error when the arrays have a length of 22 000, but the CommunicationException is thrown when arrays have a length of 44 000.

Here's my App.config file regarding the netTcpBinding part:

 

<netTcpBinding>
    <binding name="MyBindingConf"
             maxReceivedMessageSize="5000000"
             sendTimeout="00:05:00">
        <readerQuotas maxArrayLength="67108864"
                      maxStringContentLength="67108864"/>
        <security mode="None" />
    </binding>
</netTcpBinding>

 

<netTcpBinding>
    <binding name="MyBindingConf"
             maxReceivedMessageSize="5000000"
             sendTimeout="00:59:00">
        <readerQuotas maxArrayLength="67108864"
                      maxStringContentLength="67108864"/>
        <security mode="None" />
    </binding>
</netTcpBinding>

Could you point on which property to change and on which side?

P.S: It's not a timeout problem.


EDIT

I have now the same nettcpbindingconfiguration on both server and client:

<bindings>
    <netTcpBinding>
        <binding name="MyBindingConf" 
                 maxReceivedMessageSize="2147483647" 
                 maxBufferSize="2147483647"
                 maxBufferPoolSize="2147483647"
                 sendTimeout="00:30:00">
            <readerQuotas maxDepth="32" 
                          maxStringContentLength="2147483647" 
                          maxArrayLength="2147483647" 
                          maxBytesPerRead="4096" 
                          maxNameTableCharCount="16384" />
            <security mode="None" />
        </binding>
    </netTcpBinding>
</bindings>

And the same serviceBehavior:

<behaviors>
    <serviceBehaviors>
        <behavior name="Debug">
            <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
        </behavior>
    </serviceBehaviors>
</behaviors>

I then get a NetDispatcherFaultException on the client, advising me to increase maxArrayLength or maxItemsInObjectGraph. But for me, these values are already largely set for what I need to transfer and also set to the max values!

Here's the InnerException message:

The maximum array length quota (19502) or the maximum items in object graph quota has been exceeded while reading XML data. These quotas may be increased by changing the MaxArrayLength property on XmlDictionaryReaderQuotas or the MaxItemsInObjectGraph setting.

Any clue? Where does this 19 502 figure comes from?

Upvotes: 1

Views: 2857

Answers (4)

Gabe Thorns
Gabe Thorns

Reputation: 1426

On both, the server and client you have to configure the attribute of your binding, if you are exchanging large amounts of data between them. For example:

<binding name="LargeSettings" maxBufferSize="20000000" maxBufferPoolSize="20000000" maxReceivedMessageSize="20000000" closeTimeout="01:00:00" openTimeout="01:00:00" receiveTimeout="01:00:00" sendTimeout="01:00:00">
      <readerQuotas maxDepth="32" maxStringContentLength="200000000" maxArrayLength="200000000" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
      <security mode="None" />
    </binding>

Work your way from the large values to find the one that suits you.

EDIT:

In Client side, you need to configure a behavior, and set that behavior in the client endpoint. Something like this:

<system.serviceModel>
    <behaviors>
        <endpointBehaviors>
            <behavior name="debug"> <dataContractSerializer maxItemsInObjectGraph="2147483647" />
            </behavior>
        </endpointBehaviors>
    </behaviors>

And you set the behavior in the client endpoint:

<endpoint name="myEndpoint" behaviorConfiguration="debug">
    Your other settings...
</endpoint>

Hope this helps.

Upvotes: 3

Surjit Samra
Surjit Samra

Reputation: 4662

Did you try maxItemsInObjectGraph in your service behavior

 <dataContractSerializer maxItemsInObjectGraph="2147483647"/>

Upvotes: 1

ChrisNel52
ChrisNel52

Reputation: 15163

Here's a copy of a wsHttpBinding that I haved used in tests to successfully transfer huge chunks of data. I'm not saying these values are best practices, but they work to pass big chunks of data.

    <binding name="WSHttpBinding_LargeData" 
      maxBufferPoolSize="524288" 
      maxReceivedMessageSize="99999999">

      <readerQuotas 
         maxDepth="128" 
         maxStringContentLength="8192" 
         maxArrayLength="163840000" 
         maxBytesPerRead="4096" 
         maxNameTableCharCount="16384"
      />
    </binding>

Upvotes: 1

Kinexus
Kinexus

Reputation: 12904

Personally I would increase the MaxReceivedMessageSize, ensuring that maxBufferSize is also adjusted. These are the common areas that we have needed to adjust.

Upvotes: 1

Related Questions