2012-05-14 10 views
10

Escribí un sistema que usa un canal Duplex NetTcp con una devolución de llamada para funcionar como servidor de publicación/suscripción.Llamar a WCF TimeOut

¿Tengo que preocuparme por el tiempo de devolución de llamada si no se envía la conexión después de un tiempo o la tubería de devolución de llamada se mantendrá indefinidamente?

Respuesta

10

La devolución de llamada no se mantendrá indefinidamente, buscará los valores de tiempo de espera que haya establecido en su configuración. Si habilita sesiones confiables, puede establecer los tiempos de inactividad de sus clientes. Puede configurar los tiempos de espera de esta manera:

<netTcpBinding> 
    <binding 
      closeTimeout="00:01:00" 
      openTimeout="00:01:00" 
      receiveTimeout="00:10:00" 
      sendTimeout="00:01:00" 
      transactionFlow="false" 
      ......> 
     <reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="true" /> 
    </binding> 
    </netTcpBinding> 

Cuando se alcanzan estos valores y no hay todavía ninguna respuesta, el canal de comunicación se convierte criticado y es necesario volver a crear un proxy cliente para consumir el servicio. El valor predeterminado para receiveTimeout es 10 minutos, así que puede aumentar eso, pero también asegúrese de aumentar su inactivityTimeout también, su inactivityTimeout debe ser mayor que receiveTimeout.

EDIT:

Se podía seguir cambiando su receiveTimeout programación basada en los valores de su cliente envía de vuelta al servidor, la clave es mantener las nuevos valores de tiempo igual en el servicio y el cliente. Se podría ir haciendo esto en el cliente (un ejemplo que me llevo de un servicio de chat estoy haciendo con WCF y consumir con los clientes de Silverlight):

//Create different clients dynamically 
MyChatServiceClient _client1 = new MyChatServiceClient("NetTcpBinding_IMyChatService_1"); 
MyChatServiceClient _client2 = new MyChatServiceClient("NetTcpBinding_IMyChatService_2"); 

En la configuración del cliente:

<!--In your config file, define multiple endpoints/behaviors with different values based on your needs--> 
     <bindings> 
      <customBinding> 
       <binding name="NetTcpBinding_IMyChatService_1" receiveTimeout="00:01:00" ...> 
        <binaryMessageEncoding /> 
        <tcpTransport maxReceivedMessageSize="283647" maxBufferSize="283647" /> 
       </binding> 
       <binding name="NetTcpBinding_IMyChatService_2" receiveTimeout="00:22:00" ...> 
        <binaryMessageEncoding /> 
        <tcpTransport maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" /> 
       </binding> 
      </customBinding> 
     </bindings> 
     <client> 
      <endpoint address="net.tcp://192.168.1.51:4520/VideoChatServer/" 
       binding="customBinding" bindingConfiguration="NetTcpBinding_IMyChatService_1" 
       contract="IMyChatService" name="NetTcpBinding_IMyChatService_1" /> 

      <endpoint address="net.tcp://192.168.1.51:4522/VideoChatServer/" 
       binding="customBinding" bindingConfiguration="NetTcpBinding_IMyChatService_2" 
       contract="IMyChatService" name="NetTcpBinding_IMyChatService_2" /> 
     </client> 

Así se puede definir varios puntos finales o fijaciones en la configuración de su cliente o el servidor, a continuación, basado en lo que sea evento en su aplicación que puede crear una instancia _clientProxyX consumir _serviceInstanceX que tendrá diferentes unión/punto final valores pero al mismo contrato como su anterior instancia de servicio. En el ejemplo anterior, el primer enlace tiene un tiempo de espera de 1 minuto, y el segundo enlace es de 2 minutos. Un punto importante a considerar es que si desea recrear nuevos proxies de clientes como este, entonces necesita derribar su antiguo cliente proxy y crear uno nuevo, que efectivamente desconecte a sus clientes del servicio, al menos momentáneamente.

También puede modificar esos valores (openTimeout, closeTimeout etc.) programáticamente en ambos servidores al crear un nuevo host de servicio. Se puede crear un nuevo huésped, basado en una de las configuraciones de enlace que ha definido en su configuración, o crear una nueva configuración mediante programación, algo como esto:

var host = new ServiceHost(typeof(MyChatService)); 
      var webHttpBinding = new System.ServiceModel.WebHttpBinding(); 
      //Modify new timeout values before starting the host 
      webHttpBinding.OpenTimeout = new TimeSpan(1, 0, 0); 
      webHttpBinding.CloseTimeout = new TimeSpan(1, 0, 0); 
      host.AddServiceEndpoint(webHttpBinding, "http://192.168.1.51/myService.svc"); 
      //start the host after necessary adjustments 
      host.Open(); 

Esto parece bastante desordenado lo sé, pero el punto es que WCF te da mucha flexibilidad para poder modificar tus configuraciones de enlace mediante programación. Asegúrese de verificar this gran respuesta sobre la modificación de sus archivos de configuración WCF. Y también puede crear fácilmente un service configuration programmtically completo.

+0

Quiero manejar eventos periódicos, ¿sería aceptable tener un mensaje "Keep-Alive" del servidor cada x minutos y establecer el tiempo de espera en 2 * x? –

+0

Entonces, ¿desea seguir cambiando el receiveTimeout en función de lo que devuelve su cliente al servidor, correcto? No lo he hecho antes, pero no creo que sea necesariamente una mala práctica. ¿Por qué no pones los tiempos de espera en "infinito"? También podría hacerlo mediante programación de esta manera: binding.ReceiveTimeout = new TimeSpan (300,0,0,0,0); esto hará que su receiveTimeout 300 días. –