【问题标题】:Message oversized on WCF communicationWCF 通信上的消息过大
【发布时间】:2011-10-25 16:10:07
【问题描述】:

我有一个 windows 服务和一个 winform 应用程序,它们使用 WCF 通过 TCP 相互通信。

我有时不得不交换大量数据,我在客户端遇到了CommunicationException。现在我很难找到要更改的属性和位置(在服务器端还是客户端?)。

当服务器向客户端返回一个值是 2-uple(我自己的实现)的两个双精度数组时,就会出现问题:Tuple<Double[], Double[]>(两个数组始终具有相同的长度)。
我注意到当数组的长度为22 000 时没有错误,但是当数组的长度为44 000 时会抛出CommunicationException

这是我关于netTcpBinding 部分的App.config 文件:

  • 在服务器上:

 

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

您能否指出要更改哪个属性以及更改哪一侧?

PS:这不是超时问题。


编辑

我现在在服务器和客户端上都有相同的nettcpbindingconfiguration:

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

同样的serviceBehavior:

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

然后我在客户端上得到一个NetDispatcherFaultException,建议我增加maxArrayLengthmaxItemsInObjectGraph。但对我来说,这些值已经在很大程度上设置为我需要传输的内容,并且也设置为最大值!

这是InnerException 消息:

读取 XML 数据时,已超出最大数组长度配额 (19502) 或对象图中的最大项目配额。可以通过更改 XmlDictionaryReaderQuotas 上的 MaxArrayLength 属性或 MaxItemsInObjectGraph 设置来增加这些配额。

有什么线索吗? 19 502 这个数字是从哪里来的?

【问题讨论】:

  • 你的 在客户端和服务器端都设置了吗?
  • @ChrisNel52:我都更新了 Q。
  • @Otiel - 您是否使用 bindingConfiguration 属性引用您在端点中配置的绑定?如果不是,您将获得绑定的默认值,而不是您设置和预期的值。
  • @Tim:是的,我是:&lt;endpoint binding="netTcpBinding" bindingConfiguration="MyBindingConf" contract="blah blah" name="blah blah" /&gt;
  • @Otiel 这又是一个悬而未决的问题吗?赏金?如果是,那么您现在的新问题是什么:)

标签: c# wcf nettcpbinding


【解决方案1】:

如果要在服务器和客户端之间交换大量数据,则必须在服务器和客户端上配置绑定的属性。例如:

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

从大值开始,找到适合您的值。

编辑:

在客户端,您需要配置一个行为,并在客户端端点中设置该行为。像这样的:

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

然后您在客户端端点中设置行为:

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

希望这会有所帮助。

【讨论】:

  • 能否请您发布完整的异常详细信息?也许我们缺少一些东西。
  • 我用我得到的新错误更新了我的问题。请查看我的编辑。
  • 您确定您的绑定在服务器和客户端上都正确映射了吗?您的服务标签是否引用了 行为?像 ?
  • 是的。虽然我的服务器上只有&lt;service&gt; 配置,而我的客户端上只有&lt;client&gt; 配置。
  • 我不确定这是否会对您有所帮助。在客户端,您需要配置一个行为,并在客户端端点中设置该行为。像这样的东西: 你设置的行为客户端端点: 您的其他设置... .
【解决方案2】:

我个人会增加MaxReceivedMessageSize,确保maxBufferSize也被调整。这些是我们需要调整的共同领域。

【讨论】:

    【解决方案3】:

    这是我在测试中用来成功传输大量数据的 wsHttpBinding 的副本。我并不是说这些值是最佳实践,但它们可以传递大量数据。

        <binding name="WSHttpBinding_LargeData" 
          maxBufferPoolSize="524288" 
          maxReceivedMessageSize="99999999">
    
          <readerQuotas 
             maxDepth="128" 
             maxStringContentLength="8192" 
             maxArrayLength="163840000" 
             maxBytesPerRead="4096" 
             maxNameTableCharCount="16384"
          />
        </binding>
    

    【讨论】:

      【解决方案4】:

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

       <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
      

      【讨论】:

      • 我还是一样的NetDispatcherFaultException
      • 在某处上传您的示例项目并告诉我,当我将财务后台从 10 个旧的 .net 远程处理迁移到 WCF 时,我遇到了很多此类错误 :)
      • 感谢Gabobcat,我找到了答案。感谢您的帮助和您的时间! maxItemsInObjectGraph 属性是要更改的。
      • 当您在编辑的问题中说您在客户端和服务器上都有相同的配置时,我假设您在服务器端和客户端具有相同的 maxItemsInObjectGraph 设置。无论如何它都很好,你把它整理好了,我很有帮助:)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-05
      • 2010-09-27
      • 2020-03-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多