在WCF服务中传输大量数据
我在 WCF 中创建了一个 Web 服务,它返回超过 54000 个数据行,每行 10 个数据。我使用 wsHttpBinding 进行通信。该服务在数据较少(即 2000 行)时运行良好,但在尝试发送包含 50000 多行(~2MB)的大型记录集时,它会崩溃。异常信息是这样的
接收对
http://localhost:9002/MyService.svc
的 HTTP 响应时发生错误。这可能是由于服务端点绑定不使用 HTTP 协议。这也可能是由于服务器中止 HTTP 请求上下文(可能是由于服务关闭)。有关更多详细信息,请参阅服务器日志。
请不要告诉我在客户端使用分页 - 我知道它会解决问题。但我需要客户端的全部数据。
我在服务器上的服务配置是
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="MyWsHttpBinding" />
</wsHttpBinding>
</bindings>
<services>
<service name="AdminService">
<endpoint address="AdminSrv"
binding="wsHttpBinding"
contract="IAdminService"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="/Bus/IRfotoWCF" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information,
set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="True"/>
<!-- To receive exception details in faults for debugging purposes,
set the value below to true. Set to false before deployment
to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="True" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true"></serviceHostingEnvironment>
</system.serviceModel>
我的客户端配置是
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IAdminService" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None" realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost/TestService/AdminService.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IAdminService"
contract="IAdminService" name="BasicHttpBinding_IAdminService" />
</client>
</system.serviceModel>
有人帮助我在客户端和服务器端进行准确的配置吗?即使我需要将绑定从 wsHttpBinding 更改为 netTcpBinding - 我这样做也没有问题。提前致谢。
I have created a web service in WCF which returns more than 54000 data-rows with 10 data in each row. I have used the wsHttpBinding for communication. The service works well with less data (i.e. 2000 rows) but it bombs out when attempting to send large record set with 50000+ rows(~2MB). The exception message is like this
An error occurred while receiving the HTTP response to
http://localhost:9002/MyService.svc
. 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.
Please don't tell me to use pagination on the client side - I know that it will solve the problem. But I need the whole chunk of data in the client-end.
My service configuration on server is as
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="MyWsHttpBinding" />
</wsHttpBinding>
</bindings>
<services>
<service name="AdminService">
<endpoint address="AdminSrv"
binding="wsHttpBinding"
contract="IAdminService"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="/Bus/IRfotoWCF" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information,
set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="True"/>
<!-- To receive exception details in faults for debugging purposes,
set the value below to true. Set to false before deployment
to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="True" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true"></serviceHostingEnvironment>
</system.serviceModel>
My client configuration is as
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IAdminService" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None" realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost/TestService/AdminService.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IAdminService"
contract="IAdminService" name="BasicHttpBinding_IAdminService" />
</client>
</system.serviceModel>
Would someone help me out with excact configuration both in the client and server side. Even if i need to change binding from wsHttpBinding to netTcpBinding - i have no problem doing that. Thanks in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
经过大量调查终于我找到了解决方案。事实上,有很多事情需要改变。
需要在服务器端完成以下更改。
首先我必须在 httpRuntime 元素中将 maxRequestLength 设置为更大的值,才能运行更长时间的请求。
第二我引入了netTcpBinding绑定,对
maxBufferSize、maxBufferPoolSize、maxReceivedMessageSize
进行了自定义更改,值为2147483647
。第三在
serviceBehaviors
和endpointBehaviors
中添加maxItemsInObjectGraph
,如下所示(不要忘记在service
和endpoint
节点)最后我的服务器配置如下所示
现在在客户端配置上,您需要更改
maxBufferSize="2147483647" maxBufferPoolSize="524288" maxReceivedMessageSize="2147483647"
并且还需要添加
maxItemsInObjectGraph="2147483647"
端点行为配置。现在,我可以在 5.30 分钟内传输 30000 行,其中查询执行 10 秒,因此传输时间为 5.20 分钟 - 仍然很多。
请随意发表评论和任何改进建议。
After a lot of investigation finnally i got the solution. Actually a number of things need to be changed.
The following changes needed to be done in Server-side.
First I had to set a maxRequestLength to a larger value in my httpRuntime element to run the request for longer period.
Second i introduced netTcpBinding binnding with custom changes on
maxBufferSize, maxBufferPoolSize, maxReceivedMessageSize
with a large value of2147483647
.Third add
maxItemsInObjectGraph
in both of theserviceBehaviors
andendpointBehaviors
like bellow (dont forget to mention the behaviour names in theservice
andendpoint
node)Finally my server configuration looks like this
Now on the client-side configuratioin you need to change the
maxBufferSize="2147483647" maxBufferPoolSize="524288" maxReceivedMessageSize="2147483647"
and also you need to add
maxItemsInObjectGraph="2147483647"
in endpoint behaviour configuration.Now i can transmit 30000 rows within 5.30 min where the query executed for 10 sec so the transmission time is 5.20 min - still a lot.
Feel free to comment and any suggestion for improvement.
如果您查看绑定详细信息,它们在服务器端和客户端上并不完全匹配。 maxBufferSize、maxBufferPoolSize、maxReceivedMessageSize 的属性也将在服务器端定义。然后您需要根据您正在查看的大小输入值。
If you look at the binding details they do not match entirely on the server and that of the client side. The attributes for
maxBufferSize, maxBufferPoolSize, maxReceivedMessageSize
are to be defined in the server side as well. And then you need to put the values according to the size you are looking at.对于大量数据,不要使用 WCF 上的 for 循环,而是使用用户定义的表类型(如果您使用的是 SQL)。它将把时间从 6 分钟减少到 15-20 秒。
Instead of using for loop over WCF for bulky data , Use user defined table type ( if you are using SQL) . It will reduce the time from 6 min to 15-20 sec.