Why is the first http request on data so slow?
I'm using something on the following lines: Doing 3 HTTP requests in a row (one after each other) and then wait a given time and loop again with doing the 3 HTTP requests.
I'm using keep-alive which is basically also working but on the first HTTP request there is a 2 second penalty each time I start with the 3 HTTP request. Only the first HTTP request has this 2 second penalty. If I lower the time waiting between the consecutive HTTP requests to something like 200ms all of the request are fast without having the first one seeing this 2 second penalty.
Obviously this sounds like the first request might not use the keep alive connection but that is actually not the case. I run tcpdump on the server and I can clearly see that all requests are using the same TCP connection without closing and building up again a new connection. The keep alive setting on the server is set to 60s while the time waiting on the app is for example 5 seconds. Also when I switch to WIFI this behavior I cannot see. With the same time waiting all requests are fast.
The http connect code is using HttpURLConnection and looks like the following:
m_res.error = null;
HttpURLConnection connection;
try {
connection = (HttpURLConnection)(new URL(m_url + "/" + m_call.command).openConnection());
connection.setDoOutput(true); // triggers POST.
connection.setDoInput(true);
connection.setRequestProperty("Accept-Charset", m_charset);
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=" + m_charset);
connection.setRequestProperty("Connection", "Keep-Alive");
connection.setRequestProperty("Accept-Encoding", "gzip");
//connection.setChunkedStreamingMode(0);
OutputStream output = null;
try {
output = connection.getOutputStream();
output.write(m_call.query_string.getBytes(m_charset));
InputStream response = null;
try {
response = connection.getInputStream();
if ("gzip".equals(connection.getContentEncoding())) {
response = new GZIPInputStream(response);
}
}
catch (IOException e) {
response = connection.getErrorStream();
}
if (response == null) {
m_res.error = "Connection Error";
}
else {
m_res.body = getAsString(response);
m_res.status = connection.getResponseCode();
}
}
catch (IOException e) {
e.printStackTrace();
m_res.error = "Connection Error";
}
finally {
if (output != null)
try {
output.close();
} catch (IOException logOrIgnore) {}
}
}
}
I think one possible answer to this is that the devices data connection on a layer below IP is changing its status e.g. maybe there is some sort of standby status which kicks in when there is no incoming or outgoing data for a given time e.g. like in my example 5 seconds.