2

I'm going to develop an android application which send some requests to server. These request may take long time to be processed in server-side; May be 10 seconds, 1 minute or even longer. I send my requests using HTTP methods to server (such as get or post). I want to know how can I be informed later of the results of my request on server? In other words how can I receive response of my request from server considering this long delay.

Which method or technology can be used to handle this situation?

Update: My question is not about how to keep an HTTP connection open for long time or how to make retries. Since first HTTP request can be responded with something like an acknowledge (means your request is in progress) however I want to know how can I receive response of a request which belong to long time ago. enter image description here

Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
VSB
  • 9,825
  • 16
  • 72
  • 145
  • Have you considered using an [async task](https://developer.android.com/reference/android/os/AsyncTask.html) to run the request in a background thread? – Octavian Mărculescu Oct 25 '17 at 08:29
  • @OctavianMărculescu Yes, AsynchTask will run in background to send HTTP request but HTTP requests are time out if server take too much time to respond. – VSB Oct 25 '17 at 08:52

4 Answers4

2

Keeping socket connection open for more than 1 minute does not sound like a good idea.

I would recommend Firebase Cloud Messaging for the purpose.

Just post the data to the server. And after the server completes the task, it will send back the result to the app.

As you said there is no guarantee for FCM messages, delivery failure of FCM messages are rare. If the message isn't received in the device within the expected time, you may make another call to the server and request for the result of older server call.

Nabin Bhandari
  • 15,949
  • 6
  • 45
  • 59
0

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

Good library for making async http requests.

You can use

 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
    }
});
Kutlu Ozel
  • 182
  • 1
  • 7
  • So the connection will will be open for all the period of request-response? – VSB Oct 25 '17 at 08:47
  • true, and you will not freeze main thread. If your api is also working in asynchronous way, you will get noticed when both sides are finished and done. – Kutlu Ozel Oct 25 '17 at 08:50
  • HTTP connection will time out if server take 15 minutes to respond to a request so the connection will drop and no response will be received. – VSB Oct 25 '17 at 08:52
  • After your edit ; Your approach is and asking style is not correct. You should split work into small pieces like video streaming, or u should use a notification alike mechanism. first send request with a key to trigger your evaluation. then a request with this key to check previous request is complete or not, if complete send result, if not check again. – Kutlu Ozel Oct 25 '17 at 11:09
0

If you use Volley to handle your request and response, you can adjust the default timeout.

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

By default, I think DEFAULT_TIMEOUT_MS is set to 2.5 seconds, so in my example I'm keeping it open, waiting for a response for 7.5 seconds. You can extend this, but I'd recommend speeding up the server before extending this too far?

iaindownie
  • 1,046
  • 12
  • 28
  • Processing request on server is human-dependent. So it is not possible to speed it up. By the way retrying for to much time, will lead to asking server for a single request several times. – VSB Oct 25 '17 at 08:49
0

First of all, if you need to make a long running task, your best option is using android services. In your case, you'll want to use a service that lasts only for your network operation to complete, so you'll need an IntentService, here's a simple and official doc to setup your service.

After that, you'll want to setup a BroadcastReceiver in your activity to receive data you'll have to send at the end of your intentService.

As for your time out concerns, @iaindownie did answer that.

Hope this helps

Nikolai
  • 256
  • 2
  • 13
  • As i explained for @iaindowni, HTTP time out is so much probable in my application due to long processing time of requests. So trying to much times will impose load to my server without any good reason. My challenge is to send request and receive response in one-to-one relation and not adding any more load to client or server. – VSB Oct 25 '17 at 09:02
  • In this case, you'd have to use apache HTTPClient not included in SDK anymore I reckon. You could then control connectionTimeOut, requestTimeout, socketTimeOut and so forth and avoid retries. You would have, however, to specify some maximum time (5 minutes?). On the other hand, I would recommend you store the results of your request on the server side somehow, and the try to periodically retrieve that result through another web service. But I guess that's not an option, is it? – Nikolai Oct 25 '17 at 09:17
  • 1
    Ok, sorry, you want to send data back to device without him asking for it, right? Well in that case you'll need to push a notification as @NabinBhandari as been saying. Otherwise, you should store the result somewhere and then retrieve it from device with another WS. Sorry for the misunderstanding – Nikolai Oct 25 '17 at 09:26