2009-08-12 14 views
7

Estoy intentando registrar lo que está sucediendo cuando el cliente obtiene un tiempo de espera en una llamada al servicio web.Cómo: Servicio web y manejo de tiempos de espera del cliente en el servicio web?

Eche un vistazo al código de HelloWorld a continuación. Esto es lo que deseo hacer, pero parece que IsClientConnected no funciona, ya que siempre vuelve verdadero.

[WebMethod] 
public string HelloWorld() { 
    //.. Do the Webservice stuff 
    if (!Context.Response.IsClientConnected) { 
     //Log some vital info about this call that timed out... 
    } 
    return "The WebService Result"; 
} 

¿Alguien conoce otra forma de verificar el estado de la llamada al servicio web?

Cuando los clientes se desconectan de una llamada de servicio web, no hay excepciones lanzadas en el servicio web. El código continúa ejecutándose hasta que finalice y luego devuelve su resultado a la nada (ya que la conexión está cerrada).

+3

La versión de IIS juega un papel importante en la precisión de IsClientConnected. Estoy ansioso por ver qué han surgido otros para resolver el mismo problema * sin * sondeo. – Marc

Respuesta

0

Espero que cada llamada de servicio web sea una solicitud/respuesta. En el caso de un error como el servicio no disponible o los tiempos de espera, se esperaría una excepción.

¿Es posible rodear la llamada con un try catch?

+0

No hay excepción lanzada dentro del servicio web cuando el cliente agota el tiempo de espera. Simplemente termina y "envía" el resultado a la nada. – Wolf5

+0

aha, entonces estás hablando del lado del servidor, no del lado del cliente. Lo siento, no estaba claro para mí. – djna

-1

Es mejor suscribirse a algún tipo de evento que verificar alguna bandera. Básicamente, ASP.NET está cancelando la solicitud porque tarda más que el valor de tiempo de espera configurado (configuración executionTimeout en el elemento httpRuntime). Sin embargo, no estoy tan seguro de si hay tal evento del tiempo de ejecución de ASP.NET. Aparentemente, tampoco plantea ninguna excepción. Parece que hay una desconexión entre su servicio y el tiempo de ejecución de ASP.NET en este caso particular. Me interesaría saber si hay una forma/truco para lograr lo que buscas.

Mientras tanto, puede buscar en los contadores de rendimiento de ASP.NET. Hay uno llamado 'Solicitudes caducadas'. Puede incluir solicitudes que agotaron el tiempo de espera mientras se espera en una cola o durante la ejecución. Puede leer ese contador de rendimiento para su servicio web al principio y al final de su método web. Si el número saltó, eso significa que se agotó el tiempo de solicitud. Puede no significar necesariamente que el salto corresponde a esa solicitud en particular, pero en cualquier caso, aún puede registrar cierta información, como los parámetros pasados ​​al método web, el tiempo transcurrido, etc. que podrían ser útiles. También puede aumentar el valor de executionTimeout en web.config para permitir más tiempo mientras trata de optimizar su método web para ejecutarlo más rápido si tiene clientes que necesitan una solución inmediata.

Si se trata de un servicio web de asmx, es posible que desee examinar el evento Session_End en global.asax. Se puede llamar cuando ASP.NET mata la solicitud.

Solo algunas ideas.

+1

-1: ¿Qué te hace pensar que la solicitud es "asesinada"? Todo lo que sabe es que el cliente obtiene un tiempo de espera. –

+0

¿Qué te hace pensar que él no es? Puede ser que debas comenzar a concentrarte más en dar respuestas que tratar de encontrar errores con las publicaciones de otras personas. Estamos tratando de darle a OP algunas direcciones y sugerencias. Al final, él tiene que decidir cuál es el más adecuado o el mejor para su problema. Solo tenemos información limitada para trabajar y hacer suposiciones en contra. –

+1

"él"? Él está asumiendo que el servicio será notificado si el cliente "desconecta". Ese no es el caso. También está asumiendo que el cliente se desconecta. Todo esto se infiere del hecho de que el cliente agota el tiempo de espera. El hecho es que todo lo que sabemos es que el cliente agota el tiempo. –

0

Esto dependerá de los detalles del marco del servicio web que esté utilizando. Por lo que muestra, no me sorprendería si no hay un mecanismo para detectar esto.

Tenga en cuenta que, en general, un servicio web no necesita estar ni siquiera usando un transporte como HTTP, puede responder por medio de colas o incluso por correo electrónico. En general, no puede, como la implementación del servidor de un simple servicio web, asegurarse de que su cliente haya visto la respuesta. ¿Qué inferirías si tu prueba funcionara? En el instante en que hiciste la prueba, está allí, un nano segundo después de que decidiste no iniciar sesión, pero antes de que regreses, se fue. No existe una relación transaccional entre el Cliente y el Servidor en SOAP/HTTP simple.

Existen estándares de servicios web adicionales para abordar algunos de estos problemas, pero generalmente es necesario diseñar sus servicios web en el supuesto de que la persona que llama puede no ver la respuesta. (quizás también proporcione servicios de estado, para que un cliente pueda dejar y luego regrese y pregunte "¿procesó el pedido?" 345).

Cuéntanos qué quieres lograr con este registro, quizás alguien tenga un enfoque de diseño para ayudar.

+0

Tener problemas con un servicio en un clúster, pero no sabemos cuál de los servicios del clúster es el que se agota cuando los clientes se conectan a la URL del clúster y no a la URL del servidor físico. El objetivo aquí es, en general, agregar a mis servicios web un log-to-the-windows-event en los casos en que se produce un tiempo de espera o una desconexión prematura entre el cliente y ese servidor. – Wolf5

+0

Lo hago suponiendo lo siguiente: Cuando el cliente realiza una llamada WS al servidor, se establece una conexión de socket TCP. Esta conexión permanece en vivo esperando la respuesta. Una vez que el servicio termina de procesar su código, los datos se devuelven en esta conexión. Mientras exista una conexión establecida que permanezca activa mientras el servicio esté haciendo su código, debería haber una manera de obtener el estado de esa conexión TCP. – Wolf5

+0

Así que solo quiero un registrador genérico de "conmutación por error" para todos los tipos de servicios web en los que el cliente se desconecta y que puedo agregar fácilmente al código. – Wolf5

0

El protocolo HTTP no especifica cómo el servidor puede hacer ping al cliente. El sentido de IsClientConnected - para verificar si existe alguna consulta 'insatisfecha' para renderizar HttpResponse. Y puede ser (no estoy seguro) si el cliente admite keep-connection-alive.

Piensa en tirar de la arquitectura: si tienes un método unidireccional, y un perro guardián del lado del cliente para comprobar periódicamente si se realizó el método.

+0

Es cierto. Esto fallará en una solución de sondeo, pero hasta ahora cuando he detectado tráfico de red con respecto a los servicios web, hay una Solicitud y una Respuesta. Nunca se estableció una nueva conexión HTTP para recibir el resultado, ya que eso se mostraría en un nuevo encabezado HTTP en el servidor. Así que estoy asumiendo que hay una conexión que se mantiene viva. Esta conexión será un zócalo .Net de alguna manera. Probablemente oculto, pero el peor caso accesible a través de un pequeño reflejo. Los enchufes obtuvieron un estado que puedo verificar. – Wolf5

+0

Sí, tienes razón. IsClientConnected devuelve exactamente lo que describes. Keep-alive es solo una bandera de optiomización, pero no la regla. Es por eso que habla de la posibilidad (solo) de transferir algo más en el mismo zócalo. – Dewfy

0

Creo que para que IsClientConnected devuelva false, la parte de su código de servicio web que dice "// .. Do the Webservice stuff" tendría que tardar más en ejecutarse que la configuración de tiempo de espera del cliente. Probablemente pueda simular esto configurando el tiempo de espera del cliente en 60 segundos y colocando un Thread.Sleep (70000) en su código de servicio web antes de la llamada IsClientConnected.

Sin embargo, no creo que esto pueda dar como resultado que IsClientConnected devuelva falso. El tiempo de espera en una solicitud de servicio web y restablecer la conexión al servidor son dos bestias diferentes. Si Response tiene un método llamado IsClientStillWaitingForThisWebServiceCallToReturn, puede hacer lo que desee.

Creo que podría obtener IsClientConnected para devolver falso si desconectó físicamente el cliente de la red mientras el método del servicio web todavía estaba en la parte antes de la comprobación IsClientConnected, pero supongo que esto no es lo que desea.

+0

Mi concepto de pruebas es solo una aplicación de servicio web ejecutando un sueño como usted mencionó y otra aplicación llamando a ese servicio web con un tiempo de espera de 100 ms. La aplicación termina con un error = la conexión está cerrada. Luego, la aplicación llega a IsClientConnected, que sigue siendo True y devuelve exit sin errores. – Wolf5

+0

Como dije, el tiempo de espera del cliente en una solicitud de servicio web y que el cliente restablezca la conexión al servidor no son lo mismo, por lo que su resultado aquí es exactamente lo que esperaría.IsClientConnected devuelve True porque el cliente todavía está conectado al servidor (aunque la llamada al servicio web ha expirado). – MusiGenesis

+1

El tiempo de espera en una llamada de servicio web es algo que ocurre solo en el lado del cliente, y el servidor no sabrá nada al respecto. – MusiGenesis

1

No creo que haya una excepción en general. Incluso si el servicio enviara una respuesta larga, de modo que la ventana de transmisión saliente se cerró, y se agotó el tiempo de espera para poder enviar bytes, todo esto ocurriría después de que el método web regresara a ASP.NET.

Lo que debes hacer es aprender qué métodos web tardan demasiado. Puede comenzar a hacer esto al activar el seguimiento, como se muestra en "Enabling Tracing in ASP.NET Web Services". Es posible que deba ir más allá y perfilar el servicio para ver dónde se está gastando el tiempo.

También debe mirar con cuidado los registros de eventos. En particular, busque eventos de advertencia del origen del evento "ASP.NET". Estos provienen del ASP.NET Health Monitoring. Le recomiendo que conozca el sistema de Monitoreo de Salud, ya que puede hacer muchas cosas por usted que usted mismo debería escribir, simplemente a costa de la configuración.

+0

Investigaré el Control de salud. Me temo que el rastreo será mortal. Hay MUCHO tráfico de estos servicios de diferentes tipos de clientes. Para mal, no parece haber una manera de detectar las desconexiones entre un cliente y un servicio web desde el lado del servicio web. Si hay, espero que alguien ilumine este hilo. – Wolf5

+0

¿Qué versión del sistema operativo está ejecutando? Vista y Server 2008 tienen un EtwTraceListener que se conecta al subsistema "Event Tracing for Windows", que es lo suficientemente rápido como para que los controladores del dispositivo lo utilicen. –

+0

2003 en los servidores. – Wolf5

0

he creado un sencillo cliente de prueba y ajuste mi solicitud de tiempo de espera de 100 ms

 HttpWebRequest MakeRequest = (HttpWebRequest)WebRequest.Create("http://localhost:55959/ScanServer.asmx"); 
     if (MakeRequest == null) 
     { 
      throw new Exception(); 
     } 
     HttpWebResponse PostResponse = null; 

     MakeRequest.Method = "POST"; 
     MakeRequest.AuthenticationLevel = System.Net.Security.AuthenticationLevel.None; 
     MakeRequest.UserAgent = "testing"; 
     MakeRequest.Timeout = 100; 
     MakeRequest.ContentType = "application/soap+xml; charset=utf-8;"; 

     try 
     { 
      byte[] PostBytes = UTF8Encoding.UTF8.GetBytes(PostData); 
      MakeRequest.ContentLength = PostBytes.Length; 

      Stream RequestStream = MakeRequest.GetRequestStream(); 
      RequestStream.Write(PostBytes, 0, PostBytes.Length); 

      PostResponse = (HttpWebResponse)MakeRequest.GetResponse(); 
     } 
     catch 
     { 
      throw; 
     } 

Dentro de una llamada de servicio Web de SOAP durante la depuración esperaba en un punto de equilibrio hasta que el cliente recibió la excepción de tiempo de espera. Entonces el valor de Context.Response.IsClientConnected se configuró en falso. También utilicé Fiddler para enviar una solicitud y cuando en el punto de interrupción del servidor aborté la sesión. De nuevo, el valor se estableció en falso.

No entiendo por qué está viendo un tiempo de espera sin poder registrar datos al verificar IsClientConnected a menos que el tiempo de espera esté en la conexión inicial con su servidor.

Cuestiones relacionadas