HttpsurlConnection e conexões intermitentes
-
24-09-2019 - |
Pergunta
Espero que alguém possa me ajudar com conexões intermitentes que estou usando o código com httpsurlconnection. O código que estou usando está abaixo:
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.setReadTimeout(10 * 1000);
if conn.getResponseCode() != 200) {
Log.v(TAG, "error code:" + conn.getResponseCode());
}
A conexão funciona pela primeira vez sempre quando a uso para puxar um arquivo JSON. No entanto, quando uso a conexão novamente para enviar um comando, ela sempre falha na primeira vez. Em seguida, normalmente funciona se eu enviar o comando rapidamente (dentro de 5 segundos), mas falhar se eu esperar um pouco. Eu não acho que seja um problema SSL porque ele se conecta na primeira vez corretamente, mas eu poderia estar errado aqui. Eu também tentei muitas variações diferentes, como adicionar:
conn.setUseCaches(false);
conn.setRequestProperty("Connection","Keep-Alive");
conn.getHostnameVerifier();
conn.getSSLSocketFactory();
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setRequestMethod("POST");
conn.wait(100);
No entanto, eu não tive sorte. Qualquer ajuda seria muito apreciada.
Solução
Tentar System.setProperty("http.keepAlive", "false");
antes de você
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
Outras dicas
Experimente este código - ele funciona de maneira confiável para mim:
public static final String USER_AGENT = "Mozilla/5.0 (Linux; U; Android 1.1; en-us;dream) AppleWebKit/525.10+ (KHTML, like Gecko) Version/3.0.4 Mobile Safari/523.12.2";
private DefaultHttpClient getThreadSafeHttpClient() {
final HttpParams params = new BasicHttpParams();
params.setParameter("http.useragent", USER_AGENT);
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(params, "UTF-8");
final SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
final SSLSocketFactory sslSocketFactory = SSLSocketFactory.getSocketFactory();
sslSocketFactory.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
registry.register(new Scheme("https", sslSocketFactory, 443));
final ThreadSafeClientConnManager manager = new ThreadSafeClientConnManager(params, registry);
final DefaultHttpClient httpclient = new DefaultHttpClient(manager, params);
// how to handle retries
final HttpRequestRetryHandler myRetryHandler = new HttpRequestRetryHandler() {
public boolean retryRequest(final IOException exception, final int executionCount, final HttpContext context) {
if (executionCount >= 5) {
// Do not retry if over max retry count
return false;
}
if (exception instanceof NoHttpResponseException) {
// Retry if the server dropped connection on us
return true;
}
if (exception instanceof SSLHandshakeException) {
// Do not retry on SSL handshake exception
return false;
}
final HttpRequest request = (HttpRequest) context.getAttribute(ExecutionContext.HTTP_REQUEST);
final boolean idempotent = !(request instanceof HttpEntityEnclosingRequest);
if (idempotent) {
// Retry if the request is considered idempotent
return true;
}
return false;
}
};
httpclient.setHttpRequestRetryHandler(myRetryHandler);
return httpclient;
}
Apenas um pouco de adição à resposta do M6TT acima:
private static void disableConnectionReuseIfNecessary() {
// HTTP connection reuse which was buggy pre-froyo
if (!Constants.SUPPORTS_FROYO) {
System.setProperty("http.keepAlive", "false");
}
}