I am trying upload multiple photos to server. For fast upload, I am compressing photos before upload. So After this, uploading is super fast when I am connected with Wifi. But in mobile data, taking 5 to 6 minutes. So Searched a bit and found the problem. In OkHttpClient I am setting write time out for 60 seconds. This write time is out getting resetted after one byte transfer to server. So its taking more time for more bytes. How to solve it.
This is the site where I learned about Time outs in Okhttp,
https://futurestud.io/tutorials/retrofit-2-customize-network-timeouts
---> I think of using CountDownTimer after making a retrofit call. So if timer is over then I need to show alert as failed or retry. But I doen't know where to use it.
So anybody give me better solution for this.
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder
.connectTimeout(1, TimeUnit.MINUTES)
.readTimeout(60, TimeUnit.SECONDS)
.writeTimeout(60, TimeUnit.SECONDS)
.build();
OkHttpClient okHttpClient = builder.build();
Related
I have a case where some users end up in a loop of requesting #GET API call too often.
Too often = 10-20x every second.
Currently, I've not located the problem and it seems that it's not going to be an easy fix, but I was wondering, is there a possibility to set some kind of limitations on Retrofit2, where if the app goes into some kind of loop where single API request is called so many times, it actually ignores these requests, for instance, do 1-5x same requests in a second max. or something similar?
How could this be done (from a networking library settings perspective)? (Till I find the root cause, I'd like to protect backend)
According the this answer you can use dispatcher as below:
Dispatcher dispatcher = new Dispatcher();
dispatcher.setMaxRequests(1);
OkHttpClient client = new OkHttpClient.Builder()
.dispatcher(dispatcher)
.build()
After then you will be able to send one request on a time.
My android application consume a service that returns a PDF file that contains certain data of the user, the problem is that when the service takes more than 5 seconds without responding the connection closes but the request is still open so new connections are made and then a timeout exception is launched.
if the response takes less than 5 seconds everything is ok.
this is a capture of the petition observed with charles made in the app.
I'm using okhttp3 and retrofit. this is how i build the client
val builder = OkHttpClient.Builder()
.readTimeout(1, TimeUnit.MINUTES)
.connectTimeout(1, TimeUnit.MINUTES)
.writeTimeout(1, TimeUnit.MINUTES)
.authenticator(tokenAuthenticator)
.addInterceptor(HeaderInterceptor(dataProvider))
I think the problem is about sockets or something but i cant find anything about it.
I have a server that support 1 api call at a time, i have tried adding Dispatcher to my retrofit Okhttp client like this:
Dispatcher dispatcher = new Dispatcher();
dispatcher.setMaxRequests(1);
OkHttpClient.Builder httpClient = new OkHttpClient.Builder()
.connectTimeout(20, TimeUnit.SECONDS)
.writeTimeout(60, TimeUnit.SECONDS)
.readTimeout(2, TimeUnit.MINUTES)
.dispatcher(dispatcher);
but that did not worked as expected ,
Dispatcher enqueue api calls connections and does not wait for
response but i want to wait for one api call response and then start
a next one
In the meantime during one api call next one if requested should wait before the first api call give reponses.
What can be done in this case, Any suggestions ?
Maybe you can send requests via execute method of Retrofit. See this
I've noticed from profiling that when my OkHttpClient is being created by the builder, TrustManagerFactory.getTrustManagers seems to be taking a long time and is blocking my UI thread on startup. It takes about 111 millis to complete.
Not being extremely familiar with TrustManagers, I was wondering if there might be a faster method that's still secure to provide these to the OkHttpClient, and remove this as a concern.
In the mean time, I'll see if I can't defer the creation of my OkHttpClient to a background thread.
You should be able to call
OkHttpClient client = new OkHttpClient.Builder().sslSocketFactory(sslSocketFactory, trustManager).build();
https://github.com/square/okhttp/blob/4568075b1a163bec48a8598917e6d6bcc9b2d96b/okhttp/src/main/java/okhttp3/OkHttpClient.java#L655
But ultimately this is doing what you will need to do, triggering the JVM to load loading SSL related classes, load CA certificates from the system etc. So it seems unlikely this is a performance win.
Creating the OkHttpClient on a background thread sounds like the best option.
I have used retrofit creating new objects each time I use a webservice . The webservice response time is good . But when tried within the app it slows down.
Does this effect the response?
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(ApiConstants.BASE_URL)
.addCallAdapterFactory(new ErrorCallback.ErrorHandlingCallAdapterFactory())
.addConverterFactory(GsonConverterFactory.create())
.build();
In the Retrofit documentation the build, baseUrl, addCallAdapterFactory, addConverterFactory operations dont entablish any connections. This make sense because they are used just to prepare the Retrofit instance for communication.
Also, considering that restful servicies typically use HTTP for communication, there is no need to entablish a connection per session. The connection entablishes every time you call an operation of the webservice api.
So, creating the instance everytime will no affect in terms of communication, but it will affect the client cpu and memory resources unnecessary.
Creating a new Retrofit instance does affect the response time and I can confirm this by my own recent experience. If I created new instance for each request the response time that I was getting was >= 1700ms where as when I used single instance for API calls, I got response in <= 500 ms.