2012-01-04 82 views
5

首先,我知道做同步调用是“错误的”,并且知道“不可能”。假GWT同步RPC调用

但是,在一个很复杂的情况下(我不知道如何解释),我需要等待来自服务器的响应,我使用GWT-RPC命令实现了GWT RPC调用。

我正在寻找某种“黑客”来做这件事。

在此先感谢。

+3

不要这样做。为你的问题找到一个异步解决方案更好。 – 2012-01-04 16:16:13

+3

“首先,我知道做同步通话是”错误的“,并且知道”不可能“。” – caarlos0 2012-01-04 16:19:05

+0

这是可能的,但这并不容易,你真的想这样做吗? – jusio 2012-01-04 16:54:28

回答

5

有一个解决方案,但它是不容易的(例如,你不能翻转一个单一的参数,使其工作)。 GWT正在使用正常的JS XMLHttpRequest。在GWT中有一个覆盖类型,称为com.google.gwt.xhr.client.XMLHttpRequest。该类用于通过HTTP向服务器发送请求。每个JS XMLHttpRequest首先通过调用方法open来初始化。此方法只有很少的参数,但第三个参数指定请求是否应该是异步的。如果将其更改为false,则请求将同步。

但GWT-RPC不直接使用这个类,它通过RpcRequestBuilder使用它,而且这个类也不直接使用XMLHttpRequest,它使用的是RequestBuilder。

所以你需要做的是创造RpcRequestBuilder和RequestBuilder的定制版本(这将使用XMLHttpRequest初始化为同步)。

的你可以设置RPCRequest建设者您的GWT-RPC服务实例,通过它铸造于ServiceDefTarget。

你还想要同步GWT-RPC请求吗?

+0

母亲的上帝,努力工作。我放弃尝试这样做。我会把你的答案作为现在的权利。不管怎么说,还是要谢谢你。 – caarlos0 2012-01-04 17:35:10

8

通常情况下,在您的RPC请求的onSuccess()功能处理的东西,你会自动地“等待来自服务器的响应”。所以我假设你想阻止当前正在运行的所有代码?由于JavaScript是单线程的,并不容易,所以没有睡眠功能可以暂停程序。

但它可能是使用定时器一劈你想要做什么:

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

我没有,如果在上面的例子中this.schedule(100)作品尝试了,但你的想法,这是一个检查服务器是否每100毫秒响应一次。当然你必须在onSuccess()函数中自己设置serverResponseReceived = true。在RPC之后立即调用计时器。

+0

我已经尝试做这样的事情,但它不工作,因为我需要在吸气。无论如何,我做了一个小的解决方法,在响应来自服务器之前调用一个事件,并且在演示者中,我需要信息,我再次更新所有的小部件。这不是我的问题的最佳解决方案,但是,我发现的唯一途径... – caarlos0 2012-01-04 17:14:15

0

GWT调用XMLHttpRequest.open() whith作为其第三个参数,这意味着该调用将是异步的。我解决了测试的目的只是迫使这第三个参数是始终虚假同样需要:

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)); 
      }; 
     })(); 
}-*/; 

调用fakeXMLHttpRequestOpen()后,任何进一步的使用XMLHttpRequest将同步行动。例如:

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"); 

将呈现百达:

Service called! 
Last message 

https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/open为XMLHttpRequest.open()规范。