Как заставить клиентский движок Vaadin повторить отправку запросов на сервер?

В данный момент я экспериментирую с Java-фреймворком Vaadin и заметил, что клиентский движок не пытается повторно отправить запросы на сервер. Когда мобильная интернет-сеть слаба или непостоянна, было бы хорошо продолжать повторять отправку запросов, а не сдаваться.

Кто-нибудь знает, как добиться этого в Vaadin?


person newlogic    schedule 09.04.2014    source источник
comment
У меня есть идея, как это сделать... Расширьте ApplicationConnection, переопределите doUidlRequest(java.lang.String uri, java.lang.String payload, boolean synchronous) и doAsyncUIDLRequest(java.lang.String uri, java.lang .String payload, RequestCallback requestCallback) для хранения сведений о последнем запросе. и создайте делегат ApplicationConnection.CommunicationErrorHandler, который повторяет последний запрос в случаях, когда соединение плохое.   -  person newlogic    schedule 09.04.2014
comment
Попробуйте и расскажите нам, как это работает   -  person Gabriel Ruiu    schedule 09.04.2014


Ответы (2)


Расширения ApplicationConnection и переопределения doAjaxRequest должно быть достаточно для достижения того, что вы пытаетесь сделать. Что-то вроде этого:

public class MyApplicationConnection extends ApplicationConnection {

    private final Logger logger = Logger
            .getLogger(MyApplicationConnection.class.getName());

    @Override
    protected void doAjaxRequest(final String uri, final JSONObject payload,
            final RequestCallback requestCallback) throws RequestException {
        // wrap the original request callback handle the retries
        RequestCallback myRequestCallback = new RequestCallback() {

            private int retries = 3;

            @Override
            public void onResponseReceived(Request request, Response response) {
                int status = response.getStatusCode();
                if (status / 100 == 2) { // 2xx Successful
                    requestCallback.onResponseReceived(request, response);
                } else {
                    handleError(request, response, null);
                }
            }

            @Override
            public void onError(Request request, Throwable exception) {
                handleError(request, null, exception);
            }

            private void handleError(Request request, Response response,
                    Throwable exception) {
                if (retries == 0) {
                    logger.info("Ajax request failed.");
                    if (response == null) {
                        requestCallback.onError(request, exception);
                    } else {
                        requestCallback.onResponseReceived(request, response);
                    }
                } else {
                    try {
                        logger.info("Ajax request failed, retrying " + retries
                                + " more times.");
                        retries--;
                        MyApplicationConnection.super.doAjaxRequest(uri,
                                payload, this);
                    } catch (RequestException e) {
                        // something went wrong in the ajax send() call, so no
                        // point in retrying
                        logger.warning("Sending Ajax request failed. Cause: "
                                + e.getMessage());
                        requestCallback.onError(request, exception);
                    }
                }
            }
        };
        super.doAjaxRequest(uri, payload, myRequestCallback);
    }
}

И в вашем файле *.gwt.xml:

<replace-with class="com.example.client.MyApplicationConnection">
    <when-type-is class="com.vaadin.client.ApplicationConnection"/>
</replace-with>

Вы также можете добавить Timer или что-то еще в метод handleError, чтобы, когда сеть не работала, запрос некоторое время ждал, пока он не восстановится. Хотя это должно быть довольно тривиально.

person jupenur    schedule 02.06.2014

Я обнаружил, что это сработало для меня хорошо:

 package com.vaadin.client;

 import com.google.gwt.http.client.RequestCallback;
 import com.google.gwt.http.client.RequestException;
 import com.google.gwt.user.client.Timer;

 public class RobustApplicationConnection extends ApplicationConnection {

public RobustApplicationConnection() {
    this.setCommunicationErrorDelegate(new ErrorHandler()); 
}

private String lastURI;
private String lastPayload;
private RequestCallback lastRequestCallback;

private enum RequestType {
    AjaxRequest,
    UidlRequest
}

private RequestType lastRequestType;

protected  void doAjaxRequest(java.lang.String uri, java.lang.String payload, RequestCallback requestCallback) throws RequestException {
    super.doAjaxRequest(uri, payload, requestCallback);
    lastRequestType = RequestType.AjaxRequest;
    lastURI = uri;
    lastPayload = payload;
    lastRequestCallback = requestCallback;
}

protected  void doUidlRequest(java.lang.String uri, java.lang.String payload) {
    super.doUidlRequest(uri, payload);
    lastRequestType = RequestType.UidlRequest;
    lastURI = uri;
    lastPayload = payload;
}

private class ErrorHandler implements ApplicationConnection.CommunicationErrorHandler {

    @Override
    public boolean onError(String details, int statusCode) {
        System.out.println("retrying in quarter second ...");
        Timer t = new Timer() { 
              public void run() { 
                  if (lastRequestType.equals(RequestType.AjaxRequest)){
                        try {
                            System.out.println("retrying doAjaxRequest...");
                            doAjaxRequest(lastURI,lastPayload,lastRequestCallback);
                        } catch (RequestException e) {
                            throw new RuntimeException("RequestException");
                        }
                    } else if (lastRequestType.equals(RequestType.AjaxRequest)){
                        System.out.println("retrying doUidlRequest...");
                        doUidlRequest(lastURI,lastPayload);
                    }
              } 
            }; 

            // delay running for quarter seconds 
            t.schedule(250); 


        return true;
    }

}

 }
person newlogic    schedule 25.06.2014