WCF 绑定中的最大缓冲区大小是多少?
我有一个场景,我必须使用 WCF 服务上传一些数据,如果上传内容大小小于 1MB,我可以成功完成,但如果上传内容大小大于 1MB,我会收到这样的错误
错误消息:-
接收 HTTP 响应时发生错误 “http://localhost/abc/Admin/Services/Package”。这可能是 由于服务端点绑定不使用 HTTP 协议。这 也可能是由于 HTTP 请求上下文被中止 服务器(可能是由于服务关闭)。查看服务器日志 了解更多详情。
我认为这是关于 app.config 中绑定的缓冲区大小设置的错误。
我的 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 可能是多少?
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 response 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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我的天啊。当MS引入WCF时,他们确实应该提到它不是数据上传/下载的技术,或者至少不是直接没有额外编码的技术。
你的服务很糟糕,对于 2GB 来说它很可能无法工作,因为它使用缓冲传输和通用文本编码。这意味着每 2GB 将首先从磁盘加载到编码为 Base64 的客户端计算机内存(+33% 大小)。存储到单个 SOAP 消息并传递到服务器,整个消息必须加载到内存中进行解码和处理。任何网络问题,整个消息都会消失。任何超时,整个消息都会消失。顺便提一句。您的
MaxReceivedMessageSize
配置为 260MB = 读取 260MB 后,服务将抛出错误请求。同时运行几个这样的上传,你的服务器就死了。服务器将尽可能多地开放拒绝服务附加。
要诊断错误,请在服务器端使用 WCF 跟踪。要了解如何传输大邮件,请阅读本文。它将帮助您定义性能更好但仍然相当不可靠的服务。最好的方法是使用一些分块并通过在客户端上分解它们并在服务器上重新组合它们来在多个调用中传输大数据集。为了提高可靠性和从故障中恢复,客户端应该能够从故障块继续,而不是再次传输整个数据集。
还有其他需要考虑的功能,例如压缩以减少传输数据的大小,以及 CRC 来验证传输的数据没有因传输而变形。
恕我直言,如果没有 WCF,直接使用 HttpListener 或通用 ASP.NET 处理程序以及 HTTP 分块传输和范围标头,可以更好、更轻松地实现这一点。
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.