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

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

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

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, чтобы, когда сеть не работала, запрос некоторое время ожидал ее восстановления. Это должно быть довольно тривиально, хотя.

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

 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;
    }

}

 }
Другие вопросы по тегам