How can I force Vaadin client engine to retry sending requests to the server?

六月ゝ 毕业季﹏ 提交于 2020-01-02 05:24:10

问题


I'm experimenting with the Vaadin Java framework at the moment and I've noticed that the client engine does not retry sending requests to the server. When mobile internet network is weak or inconsistent it would be good to keep retrying sending of requests rather than giving up.

Does any one know how to achieve this in Vaadin?


回答1:


Extending ApplicationConnection and overriding doAjaxRequest should be enough to achieve what you're trying to do. Something like this:

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

And in your *.gwt.xml file:

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

You might also want to add a Timer or something to the handleError method, so that when the network is down, the request will wait for a while for it to come back up. It should be fairly trivial though.




回答2:


I found this worked well for me:

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

}

 }


来源:https://stackoverflow.com/questions/22962285/how-can-i-force-vaadin-client-engine-to-retry-sending-requests-to-the-server

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!