Fake a GWT Synchronous RPC call
Usually, by handling stuff in the onSuccess()
function of your RPC request, you'll automatically "wait the response from server". So I assume you want to block all the code currently running? Since JavaScript is single-threaded that won't be easy, there is no sleep function that just halts the program.
But it might be that a hack using a timer does what you want:
Timer checkRPCResponse = new Timer() { @Override public void run() { if (!serverResponseReceived) { this.schedule(100); } else { proceedWithProgram(); } } }; checkRPCResponse.schedule(100);
I haven't tried out if the this.schedule(100)
works in the above example, but you get the idea, which is a check if the server has responded every 100 ms. Of course you have to set serverResponseReceived = true
yourself in the onSuccess()
function. Call the timer right after the RPC.
There is a solution but it is not easy (e.g. you cannot flip a single parameter to make it work). GWT is using normal JS XMLHttpRequest under the hood. In GWT there is an overlay type for it called com.google.gwt.xhr.client.XMLHttpRequest. This class is used to send requests to the server over HTTP. Each JS XMLHttpRequest is first initialized by calling method open. This method has few parameters, but the third parameter specifies if the request should be asynchronous. If you change it to false, request will be synchronous.
But GWT-RPC doesn't use this class directly, it using it via RpcRequestBuilder, and this class is not using XMLHttpRequest directly as well, it is using RequestBuilder.
So what you'll need to do is to create customized version of RpcRequestBuilder and RequestBuilder (which will use XMLHttpRequest initialized to be synchronous).
The you can set RPCRequest builder to your GWT-RPC service instance, by casting it to the ServiceDefTarget.
Do you still want to have synchronous GWT-RPC requests?
GWT calls XMLHttpRequest.open() whith true as its third parameter which means the call will be asynchronous. I solved a similar need for testing purposes just forcing this third parameter to be always false:
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)); }; })();}-*/;
After invoking fakeXMLHttpRequestOpen(), any further use of XMLHttpRequest will act synchronously. For instance:
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");
will allways render:
Service called!Last message
See https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/open for XMLHttpRequest.open() specification.