使用HttpClient在Android中重用SSL会话

use*_*142 12 ssl session android httpclient reusability

我在使用HttpClient在Android上恢复SSL会话时遇到了很多困难.

我每隔90秒轮询一次服务器(仅适用于只有一个功能的工业设备),所以我需要恢复会话,否则数据使用从每小时几KB到最高150-200kB,这是不可持续的.服务器是在Restlet中嵌入Jetty,并且当我使用OpenSSL测试它时支持恢复SSL会话.据我所知.

我正在重用我的HttpClient对象,所以不是这样.Android有一个特定的SSLCertificateSocketFactory,我也尝试过,它似乎也没有用.

有什么我在这里完全失踪的吗?我曾经假设HttpClient会自动执行此操作,我不确定我做错了什么,互联网上的任何人似乎都没有遇到类似的问题.

我通过以下方式设置了httpClient:

    public HttpClient getNewHttpClient(Context context) {
    try {

        HttpParams params = new BasicHttpParams();
        HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
        HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);
        HttpConnectionParams.setStaleCheckingEnabled(params, false);

        HttpConnectionParams.setConnectionTimeout(params, 4 * 1000);
        HttpConnectionParams.setSoTimeout(params, 5 * 1000);
        HttpConnectionParams.setSocketBufferSize(params, 8192);

        HttpClientParams.setRedirecting(params, false);

        SSLSessionCache sslSession = new SSLSessionCache(context);
        SchemeRegistry registry = new SchemeRegistry();

        registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
        registry.register(new Scheme("https", SSLCertificateSocketFactory.getHttpSocketFactory(10*60*1000, sslSession), 444));
        //registry.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 444));

        ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);

        return new DelegateHttpClient(ccm, params);

    } catch (Exception e) {
        return new DefaultHttpClient();
    }
}

private static class DelegateHttpClient extends DefaultHttpClient {

    private DelegateHttpClient(ClientConnectionManager ccm, HttpParams params) {
      super(ccm, params);
    }

    @Override
    protected HttpContext createHttpContext() {

      HttpContext context = new BasicHttpContext();
      context.setAttribute(ClientContext.AUTHSCHEME_REGISTRY, getAuthSchemes());
      context.setAttribute(ClientContext.COOKIESPEC_REGISTRY, getCookieSpecs());
      context.setAttribute(ClientContext.CREDS_PROVIDER, getCredentialsProvider());

      CookieStore cookieStore = new BasicCookieStore(); // Create a local instance of cookie store
      context.setAttribute(ClientContext.COOKIE_STORE, cookieStore);

      return context;
    }
  }
Run Code Online (Sandbox Code Playgroud)

(我故意使用端口444)

然后我只使用简单的HttpGet和Basic授权重用HttpClient对象.

我在这做错了什么!有人,请帮忙!

use*_*142 2

它是固定的。它现在使用会话并消耗少量数据。

registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
Run Code Online (Sandbox Code Playgroud)

删除该行可以修复它,尽管 HttpClient 甚至从未使用过 http/port 80。我不知道为什么会这样。