lunes, 3 de mayo de 2010

BlazeDS: NetConnection.Call.Failed

Bueno como ya había comentado antes, durante las últimas semanas, he tenido una "batalla" con BlazeDS, y parece que finalmente a acabado con un resultado algo inesperado, quedando BlazeDS totalmente exonerado.

El problema consiste en la perdida de conexión entre el cliente y el servidor (Java). Tras realizar una llamada a un servicio si esté se demora mucho (o si colocamos un breakpoint) se pierde la conexión con el servidor y tras el timeout se informa al cliente, con un evento NetStatusEvent con el código NetConnection.Call.Failed, el cuál vuelve a realizar la llamada teniendo así varios hilos ejecutando la misma llamada.

He pasado mucho tiempo comprobando los logs (tanto de servidor como de cliente), variando las configuraciones del BlazeDS, depurando el código de BlazeDS, el código de la librería RPC del FLEX SDK (en varias versiones) sin encontrar un motivo aparente del error, ya que realmente el funcionamiento era correcto. En este proceso siempre llegaba al mismo punto que era la serialización del AMF Request, pero realmente la hacía bien, pero en ese punto era cuando perdía la conexíon.

La sorpresa salta cuando probando en otro entorno con un servidor de aplicaciones Tomcat no se reproduce el error, por lo que decidimos revisar el servidor de aplicaciones Jetty que usamos en desarrollo y encontramos que se debe a una actualización del servidor Jetty que hasta al fecha funcionaba correctamente, pero que había sido actualizado.

El problema radica en la versión 6.1.24 de Jetty, el cuál ha modificado la forma en que se tratan los request HTTP (probablemente exista algún bug). No he profundizado en el tema pues las versiones anteriores de Jetty funcionan correctamente y nos hemos pasado a una anterior, pero creo que el problema anda por la clase HttpParser la cual se encarga de leer (parsear) los request.

Saludos.

9 comentarios:

  1. hola, no se si me puedes ayudar o pregunto una tonteria. yo tengo un poryecto en eclipse que esta desarrollado en flex para red5 y me gustaria poder hacer una llamada a un metodo de una clase de una aplicacion en java que esta en el servidor red5.
    He intendado hacer objnetconection.call("DemoService.getListOfAvailableFLVs",obj), donde el primer parametro es el nombre de la clase y el metodo al que quiero invocar y obj es un obj Responder instanciado de la siguente forma obj = new Responder(null,null);, y no logro hacer la conexion.
    Ojala puedas ayudarme llevo ya un tiempo intentandolo.

    Muchas gracias

    ResponderEliminar
  2. Buenas.

    Lo primero decirte que no he trabajado con Red5, pero imagino que tendrás expuesto tu servicio ¿No?. Por lo que he visto Red5 va sobre Spring y es necesario crear los beans. ¿has creado un bean para DemoService? (creo que es en el red5-web.xml)

    Lo siguiente es crear un la conexión en la parte de cliente para poder conectar. Te dejo un enlace de los ejemplos en la página de Red5 en la que se realza la conexión: http://red5.googlecode.com/svn/java/example/trunk/RemoteApp/src/RemoteApp.mxml

    Asimismo asegurate de tener el puerto que usa Red5 abierto (creo que es el 1935)

    Si me das un poco más de infomación quizás pueda ayudarte más.

    Saludos

    ResponderEliminar
  3. buen con respecto a lo que posteaste yo me encontre con un problema similar. si yo corro mi aplicacion en un server linux con apache 6 en LAN todo anda de maravillas.pero el problema ocurre cuando lo subo a mi proveedor de hosting que tiene una version 5.x.x de apache y segun lo que e leido el error viene por ese lado. este es mi error y aparentemente coincide con lo que tu dices fault=[RPC Fault faultString="Send failed" faultCode="Client.Error.MessageSend" faultDetail="Channel.Connect.Failed error NetConnection.Call.Failed: HTTP: Failed: url: 'http://mihost.com/ds-console/messagebroker/amf'"]

    si tienes una posible solucion me avisas??.porque se ha posteado en distintos lugares la posibilidad de que sea un problema de version en el jre.lo cual ya descarte,solo queda la incompatibilidad de version con tomcat. uso flash builder 4 + blazeds 4 + tomcat 6 en mi servidor.

    ResponderEliminar
  4. Realmente el error no me parece el mismo, en mi caso encontraba el servicio pero se desconectaba, en tu caso parece que no encuentra el messageBroker.

    Veo que comentas que tu proveedor de servicios usa apache, ¿tiene un Tomcat por atrás en el que despliegas? Si es así tendrás que redireccionar las peticiones a messageBroker que llegan al Apache para que se envíen al Tomcat.

    Una prueba fácil es poner la dirección ("http://mihost.com/ds-console/messagebroker/amf")en el navegador. Si todo va bien mostrará una página en blanco, si falla algo mostrará el error. También puedes probar con Charles para ver si llegan las peticiones correctamente.

    ResponderEliminar
  5. bueno yo tengo un aporte que hacer.me ha sucedido lo mismo que a ti.de modo local y en un hosting.con apache tomcat.
    no encontre solucion aparte en una aplicacion que funcionaba perfectamente.asi que leyendo me encontre con el problema de que no funciona blazeds 4 en servidores con apache tomcat que sean versiones menores a la 6.y mi proveedor me ofrecia apache tomcat ver 5.x,en el trabajo tenemos un server con tomcat 6.0.x y funciona de maravillas.pero probe con el 5.x y no andaba.tiraba el error amf

    ResponderEliminar
  6. Muy bueno el aporte. Por lo que se ve, a partir de ahora habrá que tener muy en cuenta las versiones de BlazeDS y la del servidor de aplicacioens que utilicemos.

    Una pregunta. ¿El BlazeDS que usaste fue el binario descargado o lo compilaste a partir del fuente? ¿Quizás se compiló con Java 1.6 y por eso da problemas? Sería cuestión de probarlo.

    ResponderEliminar
  7. la verdad no recuerdo.creo que no compile nada.directamente lo desempaquete. m........ me has plantado la duda.pero igual consulte me fije en mi viersion de jdk y era la 1.6 y en mi server tb soportaban varias versiones,asi que creeria que no era ese el problema.dado que tambien me fije en internet y probe con un server local en linux que tengo,con jdk 1.6 y tomcat ver.6 y andubo. y ellos con version jdk 1.6 y tomcat 1.5 no andubo. si ya funciona en una lan.no deberia de haber problemas en wan

    ResponderEliminar
  8. Y cual es la solución cuando no encuentra el messageBroker? ya hice pruebas y si es lo que pasa, no existe la URL ej. http://localhost/webapps/ds-console/messagebroker/amf, hay que crearla? o en que archivo apunto a donde debe de ir? Gracias

    ResponderEliminar
  9. Lo primero debes asegurarte de que has definido el servlet y su mapping en el web.xml

    <!-- MessageBroker Servlet -->
    <servlet>
    <servlet-name>MessageBrokerServlet</servlet-name>
    <servlet-class>flex.messaging.MessageBrokerServlet</servlet-class>
    <init-param>
    <param-name>services.configuration.file</param-name>
    <param-value>/WEB-INF/flex/services-config.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
    <servlet-name>MessageBrokerServlet</servlet-name>
    <url-pattern>/messagebroker/*</url-pattern>
    </servlet-mapping>

    Fijate que he puesto como fichero de configuración "/WEB-INF/flex/services-config.xml". Asi que nos situamos en esa carpeta y deberíamos tener los 4 archivos de configuración del BlazeDS (services-config.xml, messaging-config.xml, proxy-config.xml y remoting-config.xml), habrá que configurar aquellos que usemos. Yo por ejemplo suelo trabajar con Remote objects asi que configuraría el remoting-config.xml (dentro del services-config incluimos el resto de fichero s que queramso usar).

    Es importante mirar como tienes definido el canal,e s algo así para AMF:
    <channel-definition id="amf" class="mx.messaging.channels.AMFChannel">
    <endpoint url="http://{server.name}:{server.port}/{context.root}/messagebroker/amf/"
    class="flex.messaging.endpoints.AMFEndpoint"/>
    </channel-definition>

    como vez la URL es http://{server.name}:{server.port}/{context.root}/messagebroker/amf/. Por eso te pregunto:
    ¿tu puerto es el puerto por defecto?
    ¿tu contexto esta definido como webapps/ds-console?

    ResponderEliminar