publicar wcf en iis
Transfiere una gran cantidad de datos en el servicio WCF (3)
Después de mucha investigación finalmente obtuve la solución. En realidad, es necesario cambiar una serie de cosas.
Los siguientes cambios deben hacerse en el lado del servidor .
Primero tuve que establecer maxRequestLength en un valor mayor en mi elemento httpRuntime para ejecutar la solicitud por un período más largo.
<system.web>
<httpRuntime maxRequestLength="102400" />
</system.web>
En segundo lugar, introduje la vinculación netTcpBinding con cambios personalizados en maxBufferSize, maxBufferPoolSize, maxReceivedMessageSize
con un valor grande de 2147483647
.
<binding name="myNetTcpBinding"
maxBufferPoolSize="2147483647"
maxBufferSize="524288"
maxReceivedMessageSize="2147483647">
Tercero, agregue maxItemsInObjectGraph
en los comportamientos de service
y en los comportamientos de endpointBehaviors
como abajo (no olvide mencionar los nombres de comportamiento en el nodo de service
y endpoint
)
<behaviors>
<serviceBehaviors>
<behavior name="myNetTcpBehaviour">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
<dataContractSerializer maxItemsInObjectGraph="2147483647"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="myNetTcpEndPointBehaviour">
<dataContractSerializer maxItemsInObjectGraph="2147483647"/>
</behavior>
</endpointBehaviors>
</behaviors>
Finalmente mi configuración de servidor se ve así
<system.web>
<httpRuntime maxRequestLength="102400" />
</system.web>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="MyWsHttpBinding" />
</wsHttpBinding>
<netTcpBinding>
<binding name="myNetTcpBinding"
closeTimeout="00:01:00"
openTimeout="00:01:00"
receiveTimeout="00:10:00"
sendTimeout="00:01:00"
transactionFlow="false"
transferMode="Buffered"
transactionProtocol="OleTransactions"
hostNameComparisonMode="StrongWildcard"
listenBacklog="10"
maxBufferPoolSize="2147483647"
maxBufferSize="524288"
maxConnections="10"
maxReceivedMessageSize="2147483647">
<readerQuotas maxDepth="32"
maxStringContentLength="8192"
maxArrayLength="16384"
maxBytesPerRead="4096"
maxNameTableCharCount="16384" />
<reliableSession ordered="true"
inactivityTimeout="00:10:00"
enabled="false" />
<security mode="Transport">
<transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
</security>
</binding>
</netTcpBinding>
</bindings>
<services>
<service name="AdminService" behaviorConfiguration="myNetTcpBehaviour">
<endpoint address="AdminSrv"
binding="netTcpBinding"
bindingConfiguration="myNetTcpBinding"
contract="IAdminService"
behaviorConfiguration="myNetTcpEndPointBehaviour"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="/Bus/IRfotoWCF" />
</baseAddresses>
</host>
</service>
<behaviors>
<serviceBehaviors>
<behavior name="myNetTcpBehaviour">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
<dataContractSerializer maxItemsInObjectGraph="2147483647"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="myNetTcpEndPointBehaviour">
<dataContractSerializer maxItemsInObjectGraph="2147483647"/>
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true"></serviceHostingEnvironment>
</system.serviceModel>
Ahora, en la configuración del lado del cliente, debe cambiar maxBufferSize="2147483647" maxBufferPoolSize="524288" maxReceivedMessageSize="2147483647"
y también necesita agregar maxItemsInObjectGraph="2147483647"
en la configuración del comportamiento del punto final.
<endpointBehaviors>
<behavior name="myEndPointBehavior">
<dataContractSerializer maxItemsInObjectGraph="2147483647" />
</behavior>
</endpointBehaviors>
Ahora puedo transmitir 30000 filas dentro de los 5,30 minutos donde la consulta se ejecutó durante 10 segundos, por lo que el tiempo de transmisión es de 5,20 min, todavía mucho .
Siéntase libre de comentar y cualquier sugerencia de mejora.
Creé un servicio web en WCF que devuelve más de 54000 filas de datos con 10 datos en cada fila. He usado el wsHttpBinding para la comunicación. El servicio funciona bien con menos datos (es decir, 2000 filas) pero se dispara cuando se intenta enviar un gran conjunto de registros con más de 500 filas (~ 2 MB). El mensaje de excepción es así
Se produjo un error al recibir la respuesta HTTP a
http://localhost:9002/MyService.svc
. Esto podría deberse a que el enlace del punto final del servicio no utiliza el protocolo HTTP. Esto también podría deberse a que el servidor ha cancelado un contexto de solicitud HTTP (posiblemente debido a que el servicio se ha apagado). Vea los registros del servidor para más detalles.
Por favor, no me diga que use la paginación en el lado del cliente, sé que resolverá el problema. Pero necesito todo el fragmento de datos en el cliente final.
Mi configuración de servicio en el servidor es como
<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>
La configuración de mi cliente es como
<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>
¿Alguien me ayudaría con la configuración de excact tanto en el lado del cliente como del servidor? Incluso si necesito cambiar el enlace de wsHttpBinding a netTcpBinding , no tengo ningún problema para hacerlo. Gracias por adelantado.
En lugar de usar for loop over WCF para datos voluminosos, use el tipo de tabla definido por el usuario (si usa SQL). Reducirá el tiempo de 6 minutos a 15-20 segundos.
Si observa los detalles vinculantes, no coinciden por completo en el servidor y el del lado del cliente. Los atributos para maxBufferSize, maxBufferPoolSize, maxReceivedMessageSize
también se definirán en el lado del servidor. Y luego debe poner los valores de acuerdo con el tamaño que está mirando.