2012-06-15 16 views
5

Necesito reintentar enviar una solicitud GWT RPC si falla (cualquier código de respuesta distinto de HTTP 200). Las razones son complejas, así que no daré más detalles sobre eso. Lo que tengo hasta ahora es que trato a todas las respuestas de solicitud en el mismo lugar como este:Cómo reenviar una solicitud GWT RPC si falla (o cómo crear una solicitud RPC persistente)?

// We override the RpcRequestBuilder.doSetCallback method and force your service to use it 
    // With this we can read the response headers if we need to. 
    ((ServiceDefTarget)serviceRPC).setRpcRequestBuilder(new RpcRequestBuilder() { 

     @Override 
     protected void doSetCallback(RequestBuilder rb, final RequestCallback callback) { 
      super.doSetCallback(rb, new RequestCallback() { 

       @Override 
       public void onResponseReceived(Request request, 
         Response response) { 
        httpResponseOkHandler(callback, request, response); 
       } 

       @Override 
       public void onError(Request request, Throwable exception) { 
        httpResponseErrorHandler(callback, request, exception); 
       } 
      }); 
     } 
    }); 

Por lo tanto, utilizando el método httpResponseOkHandler, puedo coger fallos HTTP. Pero, ¿hay alguna manera de "volver a lanzar" la Solicitud, es decir, intentar nuevamente? No quiero almacenar los parámetros de alto nivel de la solicitud de RPC, preferiría usar el contenido de la solicitud que ya estaba en línea y listo para volver a enviar.

¿Alguna idea?

Respuesta

4

Bueno, encontré la respuesta yo mismo. Entonces, es bastante limpio después de todo. Al trabajar en entornos hospitalarios muy cargados, la red tiende a ser poco confiable. Es por eso que tuve que volver a enviar las solicitudes de rpc varias veces antes de darme por vencido. Aquí está la solución:

1- Configure su creador de solicitudes especiales para capturar todas las respuestas de las solicitudes pero mantenga el generador de solicitudes.

((ServiceDefTarget)serviceRPC).setRpcRequestBuilder(new RpcRequestBuilder() { 

     @Override 
     protected void doSetCallback(RequestBuilder rb, final RequestCallback callback) { 
      final RequestBuilder requestBuilder = rb; 
      super.doSetCallback(rb, new RequestCallback() { 

       @Override 
       public void onResponseReceived(Request request, 
         Response response) { 
        httpResponseOkHandler(requestBuilder, callback, request, response); 
       } 

       @Override 
       public void onError(Request request, Throwable exception) { 
        httpResponseErrorHandler(requestBuilder, callback, request, exception); 
       } 
      }); 
     } 
    }); 

2- Ahora use el generador de solicitudes para enviar la solicitud tantas veces como desee. Una gran cosa es que el generador de solicitudes ya estaba configurado y los datos fueron serializados, lo que evita tener que almacenar los datos POJO no serializados.

// We had some server HTTP error response (we only expect code 200 from server when using RPC) 
    if (response.getStatusCode() != Response.SC_OK) { 
     Integer requestTry = requestValidation.get(requestBuilder.getRequestData()); 
     if (requestTry == null) { 
      requestValidation.put(requestBuilder.getRequestData(), 1); 
      sendRequest(requestBuilder, callback, request); 
     } 
     else if (requestTry < MAX_RESEND_RETRY) { 
      requestTry += 1; 
      requestValidation.put(requestBuilder.getRequestData(), requestTry); 
      sendRequest(requestBuilder, callback, request); 
     } else { 
      InvocationException iex = new InvocationException("Unable to initiate the asynchronous service invocation -- check the network connection", null); 
      callback.onError(request, iex); 
     } 
    } else { 
     callback.onResponseReceived(request, response);   
    } 

Esto está funcionando bien para mí, ¡úsalo a tu propio riesgo!

+0

¿Qué es requestValidation? Es un mapa? –

+0

Sí, un MAP sencillo. Tal vez no es la solución más elegante, si tiene algo que proponer, estaría encantado de verlo. –

Cuestiones relacionadas