In my application, I call some Web Serices (WS) using ksoap2 library and almost all o the time it works fast. But sometimes, the call of the WS is very slow.
I have a code like this:
beforecall = System.currentTimeMillis();
androidHttpTransport1.call(NameSpaces.NAMESPACE+UserWSMethodName.GETUSERINFO,envelope1);
Log.d("soapdebug","call duration="+(System.currentTimeMillis()-beforecall));
And generally I get 1 or 2 seconds (Max), but sometimes I get 11 seconds... And when the calls are too slow, it happens for all WS, and after a while (hours, for instance) it comes back to normal and become fast...
In wireshark, I see that for each call, the time elapsed between the call() method is invoked and the time where the server establish the the TCP connection with a [SYN] packet, is about 10 seconds so it is during this time that the time is spent, but I don't understand why this happen just sometimes.
What could be causing the problem?
It could be a device configuration?
What I have made to solve this problem was just reboot the router where the mobile device is connected.
Related
I'm using Retrofit and OkHttpClient to build a Rest API on Android.
Some time ago, i had noticed the very first request made by the api always take way longer to process than all others... At begining i didn't care because it was an acceptable time.
But suddenly the request time jumped to 60 SECONDS
All this time is waste client side, since monitoring the server i see that the processing time takes less than 1 seconds...
I was wondering what change I made that could cause such high impact, then I realized that i changed the connection timeout of OkHttp.
I had changed the value from 10 seconds to 60 seconds just for testings...
I made some experiments setting the connectTimeout to many others values and ALWAYS the first request takes the time sighly above the timeout
Does anyone know what may cause this weird behavior? how to solve it?
PS. I needed to test the api on a desktop and this problem didnt occur, i mean it is only happening on android devices [i tried several] what is the cause?
https://medium.com/inloopx/okhttp-is-quietly-retrying-requests-is-your-api-ready-19489ef35ace
It is likely failing on the first few requests and timing out. OkHTTP is automatically retrying.
builder.retryOnConnectionFailure(false);
Try turning off the auto retry and see what happens.
https://www.reddit.com/r/gfycat/comments/5y2dkm/psa_for_android_devs_how_to_work_around_ipv6/
It is likely an ipv4 vs ipv6 problem. This code prioritizes ipv4 addressses.
You could configure an EventListener in your OkHttpClient and use that to see how the time is spent.
I'm sending requests from my android phone one at a time as fast as possible to my server, and then graphing the time (x axis) vs hit number (starting at 0). After running this on Andrid for about 10 minutes, I get a graph like this:
The flat parts are unexpected. This signifies that every 3 minutes or so, there's a 1 minute lag that happens. Why might this be happening?
A few things I've noticed:
It doesn't matter if the screen is on or off
My server is not the problem. During the long pauses, I'm able to hit the endpoint on my server separately from android.
Both POST requests and requests over websockets have the same problem
It is possible the problem is my android data connection; I'm not sure how to remove this as a possible variable. It would be odd that the data connection would do this.
Can I synchronize one time on several Android devices?
For example current time is 00:00 and through the timeapi (web service) we sent this time to Android1. Due to some delay we get 00:01 instead of 00:00.
We make the same on Android2 but in this time, delay = 2sec and we get 00:02.
So can we sync these time between 2 Android devices?
Maybe you suggest another way without web serivce, via bluetooth or sent several requests to web service every 5 sec to calculate average delay?
At best I have to get 00:00 time at Android1 and Android2.
If what you want is the correct time on all devices, then you usually don't need to do anything except make sure that the built-in time synchronization is not turned off, and the time synchronization will be done via the NITZ protocol.
If your carrier doesn't provide NITZ time sync, you could use NTP.
If you want to have your own, custom time, turn off the NITZ sync, and use NTP with your own custom NTP server.
When a network connection is unavailable, the drive sdk takes a very long time to timeout -- it takes 15 mins according to this answer.
I access Drive in an AsynchTask which blocks my application. So, if there is no network connection, the application shows a ProgressDialog for 15 mins, until the time out. Possibly I could implement my own timer which kills the AsynchTask after a reasonable duration. However, it might be difficult to differentiate between a timeout and a lenghty process (like downlaoding a large file on a slow connection) and I would be concenred that there could be issues with the token access not cleaning up properly. Any suggestions for how to work around this?
A check if there is a network connection before performing the AsyncTask would help eliminate a lot of the cases, see Detect whether there is an Internet connection available on Android
Recently google introduced push-to-device service, but it's only available 2.2 and up.
I need a similar system in my app, and I'm trying to get around limitations.
The issue is battery life. Since the user must be notified immediately about the changes on the server, I thought to implement a service that would live in the background (standard Android service) and query the server for updates.
Of course, querying the server, even each second, will cost a lot of bandwidth, as well as battery, so my question is this: does it make a difference if the server is holding the response for some period of time? (the idea behind Comet type ajax request)
Works like this:
Device sends request for data update
Server gets the request and goes in the loop for one minute, checking if there are updates on each iteration
If there are updates, server sends response back with updates
If not, service goes on to the next iteration.
After a minute, it finally sends the response that no data is yet available
After response (no matter whether empty or with data) Android fires another such request.
It will definitely cost less bandwidth, but will it consume less (or even more) battery?
Holding a TCP socket (and consequently waiting for an HTTP response) as you suggest is probably going to be your best option. What you've described is actually already implemented via HTTP continuation requests. Have a look at the Bayeux protocol for HTTP push notifications. Also, check out the Android implementation here. For what it's worth, that's definitely what I would use. I haven't done any sort of analysis of it, but this allows you to minimize the amount of data transmitted over the line (which is directly proportional to the power consumption) by allowing the connection to hang for as long as possible.
In short, the way Bayeux works is very similar to what you've suggested. The client opens a request and the server waits on it. If it has something to send, it sends it otherwise it simply waits. Eventually, the request will timeout. At that point, the client makes another request. What you attain is near instantaneous push to the client from the server without constant polling and duplication of information like HTTP headers, etc.
When the phone is actively using the networks, it's battery is used more. That is to say when it sends the request and when it receives the response. It will also be using battery just by listening for a response. However, will the phone download data, checking to see if there's a response? Or will the phone just be open to receiving it and the server will push the response out to the phone? That is mainly what it depends on. If the phone is just open to receiving the response but does not actually use the network while trying to download some response the whole time it's waiting, it should use less battery.
Additionally, the phone sending a query every minute instead of every second definitely uses less battery, as far as using the networks goes. However it depends on how you make the phone hold, if you tie it up with very complex logic to make it wait it may not help battery life. That's probably not the case, however, and I would say that in all likelihood this would work out for you.
In closing, it should help the battery but there are ways you could make it in which it would not. It wouldn't hurt to write the program and then just change some type of variable (for example WAIT_TIME to 1 second instead of 1 minute) and test battery usage though, would it?