views:

486

answers:

2

I'm hoping someone could help me out with intermittent connections I'm getting using code with HttpsURLConnection. The code I'm using is below:

HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
            conn.setReadTimeout(10 * 1000); 
if conn.getResponseCode() != 200) { 
            Log.v(TAG, "error code:" + conn.getResponseCode()); 
} 

The connection works the first time everytime when I use it to pull a json file. However, when I use the connection again to send a command, it always fails the first time. It then typically works if I send the command quickly ( within 5 seconds), but fails if I wait a while. I don't think its a SSL issue because it connects the first time correctly, but I could be wrong here. I also tried many different variations such as adding:

conn.setUseCaches(false); 
conn.setRequestProperty("Connection","Keep-Alive"); 
conn.getHostnameVerifier(); 
conn.getSSLSocketFactory(); 
conn.setDoOutput(true); 
conn.setDoInput(true); 
conn.setRequestMethod("POST"); 
conn.wait(100); 

However, I had no luck. Any help would be greatly appreciated.

+1  A: 

Try this code - it works pretty reliably for me:

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;
}
DroidIn.net
Thanks ...that's a lot more complicated than my simple https url connect. I'm not sure how to exactly use it. Where would I input my url since the getThreadSafeHttpClient function doesn't have any inputs?
mrHTN
you just use it to get HttpClient and then use client as usual. Something like `HttpClient client = getThreadSafeHttpClient();`
DroidIn.net
HttpGet get = new HttpGet(url);HttpResponse response = this.client.execute(get);
DroidIn.net
DroidIn, do you advise to always set the SSLSocketFactory and HostnameVerifier even though the connection is working without it?
mrHTN
You don't have to if you are 100% sure you are not going to ever hit https. I simply have this code a s a template and set it once when I initialize HttpClient
DroidIn.net
+1  A: 

Try System.setProperty("http.keepAlive", "false"); before you do

HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
disretrospect
Perfect. This worked. I didn't know you could use "System." I'm guessing the SSL connection was being kept open before ans I moved through different activities. Thanks!
mrHTN
Yes, I think it has something to do with the errorstream not being read fully.
disretrospect