Поддельный GWT синхронный вызов RPC - PullRequest
5 голосов
/ 04 января 2012

Прежде всего, я знаю, что делать синхронный вызов "неправильно", и знаю, что "невозможно".

Но в ситуации очень сложной (я не знаю, как объяснить) мне нужно дождаться ответа от сервера, я использую реализацию команды GWT-Platform для вызовов GWT RPC.

Я искал какой-то "хак" для этого.

Заранее спасибо.

Ответы [ 3 ]

8 голосов
/ 04 января 2012

Обычно, обрабатывая данные в функции onSuccess() вашего запроса RPC, вы автоматически «ждете ответа от сервера». Итак, я предполагаю, что вы хотите заблокировать весь код, запущенный в данный момент? Поскольку JavaScript является однопоточным, что будет нелегко, нет функции сна, которая просто останавливает программу.

Но, возможно, хак, использующий таймер, делает то, что вы хотите:

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

Я не проверял, работает ли this.schedule(100) в приведенном выше примере, но вы получаете идею, которая проверяет, отвечает ли сервер каждые 100 мс. Конечно, вы должны установить serverResponseReceived = true самостоятельно в функции onSuccess(). Вызовите таймер сразу после RPC.

5 голосов
/ 04 января 2012

Есть решение, но оно нелегкое (например, вы не можете перевернуть один параметр, чтобы он работал). 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 голосов
/ 15 ноября 2016

GWT вызывает XMLHttpRequest.open () со значением true в качестве третьего параметра, что означает, что вызов будет асинхронным. Я решил аналогичную потребность в целях тестирования, просто заставив этот третий параметр всегда быть ложным:

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 ().

...