如何强制Vaadin客户端引擎重试向服务器发送请求?

时间:2014-04-09 12:17:31

标签: vaadin vaadin7 vaadin-touchkit

我正在尝试使用Vaadin Java框架,我注意到客户端引擎没有重试向服务器发送请求。当移动互联网网络薄弱或不一致时,最好继续重试发送请求而不是放弃。

有人知道如何在Vaadin中实现这一目标吗?

2 个答案:

答案 0 :(得分:1)

扩展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>

您可能还想在handleError方法中添加一个Timer或其他东西,这样当网络关闭时,请求会等待一段时间才能恢复。但这应该是相当微不足道的。

答案 1 :(得分:0)

我发现这对我有用:

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

}

 }