WCF绑定中的最大缓冲区大小是多少?

时间:2011-10-04 08:27:11

标签: wcf wcf-binding wcf-security wcf-data-services wcf-client

我有一个senario,我必须使用WCF服务上传一些数据,如果上传内容大小小于1MB,我能够成功地做到这一点,但如果上传内容大小超过1MB,我会得到一个错误这个

错误消息: -

  

接收HTTP响应时发生错误   “HTTP://本地主机/ ABC /管理/服务/包”。这可能是   由于服务端点绑定不使用HTTP协议。这个   也可能是由于HTTP请求上下文被中止   服务器(可能是由于服务关闭)。查看服务器日志   了解更多详情。

我认为在app.config中的绑定中我的bufferize设置有错误。

我的app.config文件客户端设置如下所示。

<system.serviceModel>
    <client>
      <endpoint address="http://localhost/abc/Services/Package"
        binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_PackageService"
        contract="PackageService.PackageService" name="BasicHttpBinding_PackageService" />
    </client>
    <services>
      <!-- This section is optional with the new configuration model
           introduced in .NET Framework 4. -->
      <service name="ServiceContracts.SearchServiceContract"
               behaviorConfiguration="SearchServiceBehavior">
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8080/xyz/SearchService"/>
          </baseAddresses>
        </host>
        <!-- this endpoint is exposed at the base address provided by host: http://localhost:8080/xyz/SearchService  -->
        <endpoint address=""
                  binding="wsHttpBinding"
                  bindingConfiguration="NoSecurityBinding"
                  contract="ServiceContracts.ISearchServiceContract" />
        <!-- the mex endpoint is exposed at http://localhost:8080/xyz/SearchService/mex -->
        <endpoint address="mex"
                  binding="mexHttpBinding"
                  contract="IMetadataExchange" />
      </service>
      <service name="ServiceContracts.PackageServiceContract"
               behaviorConfiguration="PackageServiceBehavior">
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8080/xyz/PackageService"/>
          </baseAddresses>
        </host>
        <!-- this endpoint is exposed at the base address provided by host: http://localhost:8080/xyz/PackageService  -->
        <endpoint address=""
                  binding="wsHttpBinding"
                  bindingConfiguration="NoSecurityBinding"
                  contract="ServiceContracts.IPackageServiceContract" />
        <!-- the mex endpoint is exposed at http://localhost:8080/xyz/PackageService/mex -->
        <endpoint address="mex"
                  binding="mexHttpBinding"
                  contract="IMetadataExchange" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="SearchServiceBehavior">
          <serviceMetadata httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="true"/>
          <dataContractSerializer maxItemsInObjectGraph="2147483646"/>
        </behavior>
        <behavior name="PackageServiceBehavior">
          <serviceMetadata httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="true"/>
          <dataContractSerializer maxItemsInObjectGraph="2147483646"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <bindings>
      <basicHttpBinding>
        <binding name="BasicHttpBinding_PackageService" closeTimeout="00:01:00"
          openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
          allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
          maxBufferSize="268435456" maxBufferPoolSize="268435456" maxReceivedMessageSize="268435456"
          messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
          useDefaultWebProxy="true">
          <readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="2147483647"
            maxBytesPerRead="268435456" maxNameTableCharCount="268435456" />
          <security mode="None">
            <transport clientCredentialType="None" proxyCredentialType="None"
              realm="" />
            <message clientCredentialType="UserName" algorithmSuite="Default" />
          </security>
        </binding>
      </basicHttpBinding>
      <wsHttpBinding>
        <binding name="NoSecurityBinding">
          <security mode="None">
            <transport clientCredentialType="None" />
            <message establishSecurityContext="false" />
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>   
  </system.serviceModel>

有人可以知道这方面的解决方法吗?我的上传大小最大可达2GB。那么我必须给出的确切的buffersize或maxReceivedMessageSize或maxStringContentLength是什么?

1 个答案:

答案 0 :(得分:2)

OMG。当MS引入WCF时,他们应该提到它不是用于数据上载/下载的技术,或者至少不是没有额外编码的技术。

您的服务很糟糕,对于2GB,它很可能无论如何都无法工作,因为它使用缓冲传输和通用文本编码。这意味着每2GB将首先从磁盘加载到编码为Base64(+ 33%大小)的客户端计算机的内存中。存储到单个SOAP消息并传递到服务器,其中整个消息将被加载到解码和处理的内存中。任何网络问题和整个消息都消失了。任何超时和整个消息都消失了。顺便说一句。您的MaxReceivedMessageSize配置为260MB =读取260MB后服务将抛出Bad请求。

同时运行几个这样的上传,你的服务器已经死了。服务器将被打开以尽可能多地拒绝服务附加。

要诊断错误,请在服务器端使用WCF tracing。要了解有关转移大邮件的信息,请阅读this article。它将帮助您定义性能更好但仍然非常不可靠的服务。最好的方法是在客户端分解它们并在服务器上重新组合它们,在多个调用中使用一些分块和传输大数据集。为了提高可靠性并从故障中恢复,客户端应该能够从故障块继续而不是再次传输整个数据集。

还需要考虑其他功能,例如压缩以减少传输数据的大小和CRC,以验证传输的数据没有因传输而格式错误。

恕我直言,如果没有WCF直接使用HttpListener或通用ASP.NET处理程序和HTTP分块传输和范围标头,这可以更好,更容易实现。