【问题标题】:receiving a response of a request which may take long time接收可能需要很长时间的请求的响应
【发布时间】:2018-04-06 06:03:17
【问题描述】:

我将开发一个向服务器发送一些请求的 android 应用程序。这些请求可能需要很长时间才能在服务器端处理;可能是 10 秒、1 分钟甚至更长。 我使用 HTTP 方法将请求发送到服务器(例如 get 或 post)。我想知道以后如何通知我在服务器上的请求结果?换句话说,考虑到这么长的延迟,我如何才能从服务器接收我的请求的响应。

哪种方法或技术可以用来处理这种情况?

更新: 我的问题不是关于如何长时间保持 HTTP 连接打开或如何重试。由于第一个 HTTP 请求可以用诸如确认之类的东西来响应(意味着您的请求正在进行中)但是我想知道如何接收属于很久以前的请求的响应。

【问题讨论】:

  • 您是否考虑过使用async task 在后台线程中运行请求?
  • @OctavianMărculescu 是的,AsynchTask 将在后台运行以发送 HTTP 请求,但如果服务器响应时间过长,则 HTTP 请求会超时。

标签: android httprequest server-side request-response


【解决方案1】:

保持套接字连接打开超过 1 分钟听起来不是一个好主意。

为此,我会推荐 Firebase 云消息传递

只需将数据发布到服务器。并且服务器完成任务后,会将结果返回给应用程序。

正如您所说,FCM 消息无法保证,FCM 消息传递失败的情况很少见。如果设备在预期时间内没有收到消息,您可以再次调用服务器并请求旧服务器调用的结果。

【讨论】:

  • FCM 消息不保证传送到安卓客户端。还有其他可靠的解决方案吗?
  • 这提供了一个很好的解决方案,但我会保留问题以找到可能的更好答案。
  • 当然。没问题。 :)
【解决方案2】:

https://github.com/loopj/android-async-http

用于发出异步 http 请求的好库。

你可以使用

 AsyncHttpClient client = new AsyncHttpClient();
client.get("https://www.google.com", new AsyncHttpResponseHandler() {

    @Override
    public void onStart() {
        // called before request is started
    }

    @Override
    public void onSuccess(int statusCode, Header[] headers, byte[] response) {
        // called when response HTTP status is "200 OK"
    }

    @Override
    public void onFailure(int statusCode, Header[] headers, byte[] errorResponse, Throwable e) {
        // called when response HTTP status is "4XX" (eg. 401, 403, 404)
    }

    @Override
    public void onRetry(int retryNo) {
        // called when request is retried
    }
});

【讨论】:

  • 那么在请求-响应的所有时间段内连接都将打开?
  • true,你不会冻结主线程。如果您的 api 也以异步方式工作,那么当双方都完成并完成时,您会注意到。
  • 如果服务器需要 15 分钟来响应请求,HTTP 连接将超时,因此连接将断开并且不会收到任何响应。
  • 编辑后;您的方法是并且询问风格不正确。您应该将工作分成小块,例如视频流,或者您应该使用类似通知的机制。首先发送带有密钥的请求以触发您的评估。然后用这个键检查前一个请求的请求是否完成,如果完成发送结果,如果没有再次检查。
【解决方案3】:

如果您使用 Volley 来处理您的请求和响应,您可以调整默认超时时间。

myRequest.setRetryPolicy(new DefaultRetryPolicy(DefaultRetryPolicy.DEFAULT_TIMEOUT_MS * 3, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));

默认情况下,我认为 DEFAULT_TIMEOUT_MS 设置为 2.5 秒,因此在我的示例中,我将其保持打开状态,等待 7.5 秒的响应。你可以扩展它,但我建议在扩展它之前加速服务器?

【讨论】:

  • 服务器上的处理请求取决于人。所以不可能加快速度。顺便说一句,重试时间过长,会导致多次向服务器请求单个请求。
【解决方案4】:

首先,如果你需要做一个长时间运行的任务,你最好的选择是使用android services。在您的情况下,您需要使用仅持续完成网络操作的服务,因此您需要一个 IntentService,这是一个 simple and official doc 来设置您的服务。

之后,您需要在您的活动中设置一个BroadcastReceiver 来接收您必须在您的intentService 结束时发送的数据。

至于你的超时问题,@iaindownie 确实回答了。

希望对你有帮助

【讨论】:

  • 正如我为@iaindowni 解释的那样,由于请求的处理时间长,HTTP 超时在我的应用程序中很可能发生。因此,多次尝试将毫无理由地对我的服务器施加负载。我的挑战是以一对一的关系发送请求和接收响应,而不是给客户端或服务器增加任何负载。
  • 在这种情况下,我认为您将不得不使用 SDK 中不再包含的 apache HTTPClient。然后,您可以控制 connectionTimeOut、requestTimeout、socketTimeOut 等并避免重试。但是,您必须指定一些最长时间(5 分钟?)。另一方面,我建议您以某种方式将请求的结果存储在服务器端,并尝试通过另一个 Web 服务定期检索该结果。但我想这不是一个选择,是吗?
  • 好的,抱歉,您想在他不要求的情况下将数据发送回设备,对吗?那么在这种情况下,您需要像@NabinBhandari 所说的那样推送通知。否则,您应该将结果存储在某处,然后使用另一个 WS 从设备中检索它。造成误会请见谅
猜你喜欢
  • 1970-01-01
  • 2016-11-07
  • 2018-07-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-15
  • 2017-03-16
  • 1970-01-01
相关资源
最近更新 更多