简体   繁体   中英

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:

  • On the server:

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

<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?

PS: It's not a timeout problem.


EDIT

I have now the same nettcpbinding configuration 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?

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.

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

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>

您是否在服务行为中尝试过maxItemsInObjectGraph

 <dataContractSerializer maxItemsInObjectGraph="2147483647"/>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM