开发者

What would be the maximum buffer size in WCF bindings?

I have a senario where i have to upload some datas using WCF service, which i was able to do successfully if the uploading content size is less than 1MB but if the uploading content size is greater than 1MB, Iam getting an error like this

Error Message:-

An error occurred while receiving the HTTP r开发者_开发知识库esponse to "http://localhost/abc/Admin/Services/Package". This could be due to the service endpoint binding not using the HTTP protocol. This could also be due to an HTTP request context being aborted by the server (possibly due to the service shutting down). See server logs for more details.

I think its an error regarding my buffersize setting in my bindings in app.config.

My app.config file client settings looks like this.

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

Can anybody know the workaround for this please? My uploading size can be upto 2GB size. So what could be the exact buffersize or maxReceivedMessageSize or maxStringContentLength which i have to give?


OMG. When MS introduced WCF they should really mention that it is not technology for data uploading / downloading or at least not directly without additional coding.

Your service is awful and for 2GB it will most probably not work anyway because it uses buffered transfer and common text encoding. It means that every 2GB will be first loaded from disk to memory of client computer encoded to Base64 (+33% size). Stored to single SOAP message and passed to server where the whole message will have to be loaded to memory decoded and processed. Any network problem and the whole message is gone. Any timeout and the whole message is gone. Btw. your MaxReceivedMessageSize is configured to 260MB = after reading 260MB the service will throw Bad request.

Running few such uploads concurrently and your server is dead. The server will be opened to denial of service attach as much as it can be.

To diagnose your error use WCF tracing on server side. To learn about transferring big messages read this article. It will help you define service which perform better but it will still be quite unreliable. The best way is to use some chunking and transfer big data sets in multiple calls by decomposing them on client and recomposing them on server. To improve reliability and recovery from failure client should be able to continue from failed chunk instead of transferring the whole data set again.

There are other features to consider like compression to reduce size of transferred data and CRC to validate that transferred data wasn't malformed by transmission.

IMHO this can be much better and easier implemented without WCF with direct usage of HttpListener or generic ASP.NET handler and HTTP chunked transport and range header.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜