¿Cómo configuro correctamente una sesión confiable WCF NetTcp Duplex?

Por favor, disculpe las preguntas y respuestas obvias, pero esta información es ampliamente malentendida y casi siempre se responde incorrectamente. Así que quería colocar esta información aquí para las personas que buscan una respuesta definitiva a este problema.

Aun así, todavía hay información que no he podido precisar. Voy a poner esto al final de la pregunta (pase a eso si no está interesado en el preámbulo).

¿Cómo configuro correctamente una sesión confiable WCF NetTcp Duplex?

Hay muchas preguntas y respuestas con respecto a este tema, y casi todas sugieren configuracióninactivityTimeout="Infinite" en su configuración Esto realmente no parece funcionar correctamente, particularmente para el caso de NetTcp (puede funcionar correctamente para los enlaces WSDualHttp, pero nunca los he usado).

Hay una serie de otros problemas que a menudo se asocian con esto: Incluyendo, el canal no falla después de que el cliente o servidor se desconectó inesperadamente, el canal se desconecta después de 10 minutos, el canal se desconecta aleatoriamente ... Excepción de lanzamiento de canal al intentar abrir ... No se puede configurar metadatos en el mismo punto final ...

Información que he descubierto, a través de prueba y error que gané con esfuerzo.

Infinite no parece ser un ajuste de configuración válido en todas las situaciones (y ciertamente, el esquema de validación de Visual Studio no lo sabe).Hay dos convertidores de configuración especiales, llamadosInfiniteIntConverter yInfiniteTimeSpanConverter que lo haráa veces trabajar para convertir el valorInfinite a cualquieraInt.MaxValue oTimeSpan.MaxValue, pero aún no he descubierto las situaciones en las que esto parece ser válido, ya que a veces funciona, y a veces no. Además, parece que algunas bibliotecas permitiránInfinite en la configuración, mientras que otros no lo harán, por lo que puede tener éxito en una parte de una configuración, pero fallar en otra.Debes configurarAMBOS inactivityTimeout yreceiveTimeout, tanto en el cliente como en el servidor. Si bien estos valores no TIENEN que ser iguales, probablemente deberían serlo, ya que probablemente causarán confusión si no lo son. (técnicamente, puedes irteinactivityTimeout a su valor predeterminado si lo desea, pero debe tener en cuenta su valor y lo que hace)inactivityTimeout deberíaNUNCA establecerse en un valor grande, mucho menosInfinte oTimeSpan.MaxValue.inactivityTimeout tiene dos funciones (y esto no se entiende ampliamente). La primera función define la cantidad máxima de tiempo que puede transcurrir en un canal sin recibir ningún mensaje de "infraestructura" u "operación". La segunda función define el período de tiempo en el que se envían los mensajes de infraestructura (la mitad del tiempo especificado). Si no se han recibido mensajes de infraestructura u operación durante el período de tiempo de espera, la conexión se cancela.receiveTimeout Especie la cantidad máxima de tiempo que puede transcurrir entre mensajes de operación solamente. Este valor se puede establecer en un valor grande, comoTimeSpan.MaxValue (especialmente si su canal se ejecuta internamente en una red confiable o en una VPN). Este valor es lo que define cuánto tiempo la sesión confiable "permanecerá viva" si no hay actividad entre el cliente y el servidor (aparte de los mensajes de infraestructura). es decir, su cliente no llama a ningún método de la interfaz, y su servidor no vuelve a llamar al cliente.establecer un cortoinactivityTimeout y un granreceiveTimeout mantiene su sesión confiable "asegurada" incluso cuando no hay actividad operativa entre su cliente y el servidor. El breve tiempo de espera de inactividad (me gusta mantener los 10 minutos predeterminados o menos) envía mensajes de "ping" de infraestructura para mantener viva la conexión TCP mientras que el tiempo de espera prolongado de recepción mantiene activa la sesión confiable. mientras que al mismo tiempo proporciona un tiempo de espera razonable en caso de desconexión.Si estableceinactivityTimeout a un valor grande, entonces la sesión confiable no será confiable ya que no tiene forma de mantener viva la conexión Tcp, ni tampoco tiene forma de verificar la integridad de la conexión. No sabrá si un usuario se ha desconectado inesperadamente hasta que intente enviar un mensaje a ese cliente y descubra que la conexión ya no está allí. Es por eso que muchas personas que usan Infinite para esta configuración recurren a la creación de un método "Ping" en su servicio, lo cual es completamente innecesario si ha configurado estas configuraciones correctamente.Si estableceinactivityTimeout a un valor mayor quereceiveTimeout entonces tampoco será confiable, ya que usted seguirá siendo gobernado porreceiveTimeout para mensajes de operación. es decir. si te olvidas de configurarreceiveTimeout y déjelo en los 10 minutos predeterminados, luego, si el usuario está inactivo durante 10 minutos, la conexión se cancelará.Cuando el cliente o el servidor se desconecta inesperadamente (la aplicación se bloquea, falla la red, alguien tropieza con el cable de alimentación, etc.), el otro lado puede no darse cuenta de inmediato. He adjuntado variosChannelFaulted manejadores de eventos en varias situaciones de prueba, y algunas veces la conexión falla inmediatamente ... otras veces no parece fallar en absoluto. Lo que he descubierto a través de prueba y error es que cuando parece que no falla, en realidad fallará después deinactivityTimeout expira en ese extremo. (así que si está configurado en 10 minutos, luego de 10 minutos llamará alChannelFaulted evento).Todavía no he descubierto por qué en algunas situaciones se da cuenta de la desconexión de inmediato, y en otras, espera a que expire el temporizador. En ambos casos, noto excepciones internas de comunicación de primera oportunidad lanzadas y manejadas por el marco, y hay llamadas para Anular la conexión ... pero de alguna manera la llamada al controlador de eventos se pierde y debe esperar el tiempo de espera. Mi sospecha es que esto está relacionado de alguna manera con el hilo.Al intentar configurar Metadata para que funcione en el canal NetTcp, he tenido resultados esporádicos. A veces funciona, a veces no. He leído muchos informes de que los metadatos no funcionan a través de NetTcp y que tiene que usar un canal Http para los metadatos, pero de hecho lo he hecho funcionar en varias ocasiones usando net.tcp: // url para generar el apoderado. Entonces cambiaría algo, volvería a compilar y ya no funcionaría. Cambiando las cosas, no volvería a funcionar. Por lo tanto, era muy confuso qué encantamiento mágico era necesario para que Metadata funcionara sobre net.tcp, compartido con el punto final en el mismo puerto (obviamente con una dirección diferente).Al configurar un punto final NetTcp y Metatdata en el mismo servicio, y al especificar configuraciones no predeterminadas para parámetros de conexión como listenBacklog y maxConnections, también debe asegurarse de que el punto final Metadata use la misma configuración, lo que generalmente significa que debe definir un enlace personalizado, ya que estas configuraciones no están disponibles desde el enlace tcp mex estándar. Esto incluye la configuraciónlistenBacklog ymaxPendingConnections entcpTransportygroupName ymaxOutboundConnectionsPerEndpoint enconnectionPoolSettings.La configuración predeterminada para la configuración ordenada de ReliableSession esTrue. Esto usa mucho más gastos generales que apagarlo. Si no necesita mensajes ordenados, le sugiero que lo desactive (necesita configurar esto en ambos lados)-

Configuración que aún necesito entender:

¿Cómo configuro correctamente el punto final de metadatos net.tcp compartido? (Agregaré un ejemplo cuando tenga la oportunidad) Actualmente, estoy especificando una URL de obtención de http para evitar el problema. Es tan inconsistente por qué a veces funciona y a veces no. Seguí recibiendo el error `No se reconoce el prefijo de URI 'al generar el proxy en Visual Studio.

¿Por qué WCF a veces falla el canal inmediatamente después de la desconexión y a veces esperainactivityTimeout ¿Expirar? ¿Qué controla / causa uno frente al otro comportamiento?

Respuestas a la pregunta(0)

Su respuesta a la pregunta