WCF, ¿cómo puedo evitar los canales con fallas si el servidor los cierra debido a la inactividad?

Mi host de servicio está configurado para cerrar la conexión después de 10 minutos

<wsHttpBinding>
    <binding receiveTimeout="00:10:00">
</wsHttpBinding>

En mi código de cliente antes de usar el servicio está validado. Si está en estado cerrado / fallado, creará uno nuevo.

    public static T ValidateService<T>(ref T service) where T : class
    {
        if (service is IClientChannel)
        {
            IClientChannel channel = service as IClientChannel;
            CommunicationState state = channel.State;
            if (state == CommunicationState.Faulted || state == CommunicationState.Closed)
            {
                // thread safe logic to create new service 
            }
        }
    }

El problema es cuando el canal está cerrado en el lado del servidor y el canal, el estado seguirá devolviendo el estado Abierto. Después de hacer una llamada remota, obtengo una excepción con falla y debido a receiveTimeout.

¿Hay alguna forma de tener tiempo de espera de inactividad en el lado del cliente? algo como receiveTimeout="00:10:00" en el servidor pero con unos segundos menos para poder cerrar un canal del cliente si no se usa y que mi ValidateService<T> La lógica creará uno nuevo si es necesario.

Por razones de rendimiento, no quiero crear un nuevo canal para cada llamada remota porque pueden ser muy frecuentes.

Me gustaría evitar tener un sondeo de latidos del corazón para cada uno de mis servicios que estoy usando en mi comunicación.

Muchas Gracias

preguntado el 08 de noviembre de 11 a las 14:11

1 Respuestas

No puedes evitar manejar Faulted y Closed ya que siempre es posible que algún problema de red o similar lleve a una situación en la que tenga que crear una nueva Channel...

EDITAR - según el comentario:

En producción, generalmente tengo una implementación de cliente que maneja ciertas excepciones al recrear el Channel y volviendo a intentar ... esto se encarga del caso que está describiendo y varios otros casos como conexión de red, etc.

respondido 08 nov., 11:20

Entonces, ¿no hay mejor manera de manejar ReceiveTimeout en el lado del cliente? Estaba pensando en tener un encuestador en el cliente para hacer un latido del corazón o bien cerrar el canal si el último período usado es lo suficientemente largo. Algo así como un ReceiveTimeout trabajando en el lado del cliente. - Marek

@marek En producción, generalmente tengo una implementación de cliente que maneja ciertas excepciones recreando el Canal y volviendo a intentar ... - Yahia

Esperaba que hubiera una forma de cerrar el canal no utilizado del lado del cliente en lugar de terminar con un canal defectuoso en el cliente. Entiendo que el canal con fallas puede ocurrir por muchas otras razones, pero me sorprende que no haya una buena manera de cerrar bien el canal no utilizado del cliente similar a ReceiveTimeout. - Marek

@marek supongamos que hay una manera de hacer eso ... entonces el resultado sería un Channel con State "Ser" Closed... ¿Qué cambiaría eso en tu código? en el mejor de los casos en el if te quitarías Faulted... No creo que eso sea calidad de producción ya que Faulted todavía podría suceder por otras razones ... - Yahia

@marek, lo que podría hacer sería crear un "grupo de clientes" similar a un "grupo de conexiones de base de datos" y luego, cada vez que obtenga un "cliente", el "grupo" lo validaría primero y lo eliminaría / recrearía adecuadamente ... cuando devuélvalo al "grupo", el "grupo" volvería a verificar si hay información específica State y descartarlo / recrearlo ... - Yahia

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.