仅在 Android 而不是 iOS 上使用 "Volley" 发出的服务器请求超时

Timeout for server request made using "Volley" only on Android not iOS

在我的一个应用程序中,我使用 Google 提供的 volley 向服务器发送请求。

问题:onErrorResponse(VolleyError error)

超时且错误对象为空

到目前为止我尝试了什么:

1) 首先我得到了空错误对象,所以使用下面的代码解决了它:

 @Override
 protected void deliverResponse(String response) {
    super.deliverResponse(response);
 }

 @Override
 public void deliverError(VolleyError error) {
     super.deliverError(error);
     DebugLog.e("deliverResponse", "getNetworkTimeMs : " + error.getNetworkTimeMs());
 }

到目前为止,当我得到错误对象 null.

时,我已经知道 timeout 发生了

2) 现在申请适用于 AndroidiOSwebtimeout 仅适用于 Android.

请求的 Volley 日志:

BasicNetwork.logSlowRequests: HTTP response for request

编辑注释:

  1. 在服务器端开发的 Web 服务对于所有三个实例(Android、Web 和 iOS)都是相同的。

  2. Timeout 当太多用户向服务器发出请求时发生。

  3. 我已经把超时设置为2分钟,虽然volley有时只会在30秒内抛出超时

  4. 我有很多关于更改服务器的答案,但由于不可能,所以请使用其他解决方案。

我还想补充一点,如果我能获得更多关于 volley 何时可以超时的信息?

我浏览过的参考资料:

Optimizing Volley

httpclient-often-times-out-using-wifi-is-going-fine-with-3g

long_xmlhttprequest_ajax_requests_timeout_on_android

已编辑:

我还设置了如下重试策略:

request.setRetryPolicy(new DefaultRetryPolicy(DefaultRetryPolicy.DEFAULT_TIMEOUT_MS * 48,
                0, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));

而且我也不想在连接超时时重试。

我如何进行有效的服务调用来解决 timeout 的问题。

我们将不胜感激。

谢谢。

public class JGet extends Request {
    private final Response.Listener listener;

    public JGet(final String url, List params,
                Response.Listener responseListener) {
        super(Request.Method.GET, NetUtils.getUrlWithParams(url, params), new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError volleyError) {
                NetUtils.dealVolleyError(volleyError, url);
            }
        });
        this.listener = responseListener;
        this.setRetryPolicy(new DefaultRetryPolicy(20 * 1000, 0, 1.0f));
        LogUtils.e("request-start--->");
        LogUtils.e(url);
        LogUtils.e(params);
        LogUtils.e("request-start--->");
    }
}

设置超时时间。

恕我直言,您可以参考以下内容:

BasicNetwork.java 中,您会发现一些信息,例如:

...
private static int SLOW_REQUEST_THRESHOLD_MS = 3000;
...
    /**
     * Logs requests that took over SLOW_REQUEST_THRESHOLD_MS to complete.
     */
    private void logSlowRequests(long requestLifetime, Request<?> request,
            byte[] responseContents, StatusLine statusLine) {
        if (DEBUG || requestLifetime > SLOW_REQUEST_THRESHOLD_MS) {
            VolleyLog.d("HTTP response for request=<%s> [lifetime=%d], [size=%s], " +
                    "[rc=%d], [retryCount=%s]", request, requestLifetime,
                    responseContents != null ? responseContents.length : "null",
                    statusLine.getStatusCode(), request.getRetryPolicy().getCurrentRetryCount());
        }
    }
...

// if the request is slow, log it.
long requestLifetime = SystemClock.elapsedRealtime() - requestStart;
logSlowRequests(requestLifetime, request, responseContents, statusLine);
...

因此,如果您的项目使用 Google 的 volley 作为模块(不是 JAR 文件),您可以更新 BasicNetwork.java,增加 SLOW_REQUEST_THRESHOLD_MS 值,也许 10000 (ms)或更多,例如。

另一种选择,根据@neuron 对以下问题的回答:

How to optimize network-queue-take in android Volley? (Volley Google IO 2013)

我认为您可以尝试在您的应用中使用以下构造函数来增加 NETWORK_THREAD_POOL_SIZE 的值:

public RequestQueue(Cache cache, Network network, int threadPoolSize) {
        this(cache, network, threadPoolSize,
                new ExecutorDelivery(new Handler(Looper.getMainLooper()))); }

P/S:如果只希望BasicNetwork.logSlowRequests: HTTP response for request行不再显示而不增加NETWORK_THREAD_POOL_SIZE,只需要注释(//) 上面的 logSlowRequests... 行(当你的应用使用 Google 的 volley 作为模块时——不是 jar 文件,不是 build.gradle 文件中的 compile mcxiaoke...

希望对您有所帮助!

因为我已经尝试了大约两个月的时间来解决这个问题,所以我没有得到任何完美的解决方案。虽然我分析了一些事实如下:

  1. 您可以升级服务器的性能
  2. 我尝试使用 HttpURLConnection 发出 web-service 请求,但仍然遇到同样的问题。

所以我认为这个问题不是 volley 特有的,但是如果你遇到这个问题,我会建议通过以下自定义来提高服务器性能 RetryPolicy:

int x=2;// retry count
request.setRetryPolicy(new DefaultRetryPolicy(DefaultRetryPolicy.DEFAULT_TIMEOUT_MS * 48,
                    x, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));

希望对您有所帮助。

随时欢迎提出建议:)

如果您找到更合适的解决方案,请在下方评论。

谢谢!

在使用 volley 向 PHP 文件发送请求时,尽量不要使用 require 语句连接到您的数据库。 我注意到仅当我使用类似(需要"init.php")之类的东西时才会超时 但是当我直接将我的数据库连接信息放在同一个文件中时,一切似乎都很好。

request.setRetryPolicy(新的 DefaultRetryPolicy( 50000, 5, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT))