2012-01-04 9 views
5

Antes que nada, sé que hacer una llamada síncrona es "incorrecta", y sé que "no es posible".Fake a GWT Llamada RPC sincrónica

Pero, en una situación muy compleja (no sé cómo explicarlo), tengo que esperar la respuesta del servidor, estoy usando la implementación del comando GWT-Platform para las llamadas GWT RPC.

Estaba buscando algún tipo de "hack" para hacer esto.

Gracias de antemano.

+3

No lo hagas. Encontrar una solución asincrónica para su problema es mejor. –

+3

"Antes que nada, sé que hacer una llamada síncrona es" incorrecto ", y sé que" no es posible ". – caarlos0

+0

Es posible, pero no es fácil, ¿realmente quieres hacerlo? – jusio

Respuesta

5

Existe una solución, pero no es fácil (por ejemplo, no se puede cambiar un solo parámetro para que funcione). GWT está utilizando JS XMLHttpRequest normal bajo el capó. En GWT hay un tipo de superposición para él llamado com.google.gwt.xhr.client.XMLHttpRequest. Esta clase se usa para enviar solicitudes al servidor a través de HTTP. Cada JS XMLHttpRequest se inicializa primero mediante el método de llamada abierto. Este método tiene pocos parámetros, pero el tercer parámetro especifica si la solicitud debe ser asincrónica. Si lo cambia a falso, la solicitud será sincrónica.

Pero GWT-RPC no utiliza esta clase directamente, sino que la usa a través de RpcRequestBuilder, y esta clase tampoco está utilizando XMLHttpRequest directamente, está utilizando RequestBuilder.

Lo que tendrá que hacer es crear una versión personalizada de RpcRequestBuilder y RequestBuilder (que utilizará XMLHttpRequest inicializado para que sea síncrono).

Puede establecer el generador RPCRequest en su instancia de servicio GWT-RPC, lanzándolo al ServiceDefTarget.

¿Aún desea tener solicitudes GWT-RPC sincrónicas?

+0

Madre de Dios, trabajo duro. Renuncio tratando de hacer esto. Voy a poner tu respuesta como correcta por ahora. Gracias de cualquier manera. – caarlos0

8

Normalmente, al manejar cosas en la función onSuccess() de su solicitud RPC, automáticamente "esperará la respuesta del servidor". Entonces supongo que quieres bloquear todo el código que se está ejecutando actualmente? Como JavaScript tiene un único hilo que no será fácil, no hay una función de suspensión que simplemente detenga el programa.

Pero podría ser que un corte usando un temporizador hace lo que quiere:

Timer checkRPCResponse = new Timer() { 
     @Override 
     public void run() { 
      if (!serverResponseReceived) { 
       this.schedule(100); 
      } else { 
       proceedWithProgram(); 
      } 
     } 
    }; 
    checkRPCResponse.schedule(100); 

No he probado si los this.schedule(100) obras en el ejemplo anterior, pero se entiende la idea, que es una compruebe si el servidor ha respondido cada 100 ms. Por supuesto, debe establecer serverResponseReceived = true en la función onSuccess(). Llame al temporizador justo después del RPC.

+0

ya he intentado hacer algo como esto, pero no funciona, porque necesito esto en un getter. De todos modos, hice una pequeña solución, llamando a un evento antes de que la respuesta venga del servidor, y, en el presentador que necesitaba la información, actualizo de nuevo todos los widgets. Esa no es la mejor solución para mi problema, pero, es la única forma en que encontré ... – caarlos0

0

llamadas a GWT XMLHttpRequest.open() con verdadero como su tercer parámetro, lo que significa que la llamada será asincrónica. He resuelto una necesidad similar para propósitos de prueba simplemente obligando a este tercer parámetro para estar siempre falsa:

private static native void fakeXMLHttpRequestOpen() /*-{ 
    var proxied = $wnd.XMLHttpRequest.prototype.open; 

    (function() { 
     $wnd.XMLHttpRequest.prototype.open = 
      function() { 
       arguments[2] = false; 
       return proxied.apply(this, [].slice.call(arguments)); 
      }; 
     })(); 
}-*/; 

Después de invocar fakeXMLHttpRequestOpen(), cualquier uso adicional de XMLHttpRequest actuará de forma sincrónica. Por ejemplo:

remoteSvc.getResult(new AsyncCallback<String>() { 
    @Override 
    public void onSuccess(String result) { 
     GWT.log("Service called!"); 
    } 

    @Override 
    public void onFailure(Throwable caught) { 
     GWT.log("Service failed..."); 
    } 
} 

GWT.log("Last message"); 

se Allways render:

Service called! 
Last message 

Ver https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/open para XMLHttpRequest.open() especificación.

Cuestiones relacionadas