Twitter4J+SPDYでSPDY通信してるかどうかの判定方法

※この記事のまとめは Twitter4JのSPDY対応について – TwitPane をご参照ください。

昨日の記事で公開したTwitter4JのSPDY拡張(twitter4j-spdy-support)ですが、本当にSPDY通信してるか心配ですよね。

色々調べてみたところ、一応下記のようなコードで Twitter オブジェクト(twitter)から SPDY のコネクションプール数を取得できることが分かりました。

String message = "SPDY : ";
if (!twitter4j.internal.http.alternative.HttpClientImpl.sPreferSpdy) {
    message += "Disabled";
} else {
    message += "Enabled(";
    try {
        final Class<?> clazz = Class.forName("twitter4j.TwitterBaseImpl");
        final Field f1 = clazz.getDeclaredField("http");
        f1.setAccessible(true);
        
        // wrapper = twitter.http
        final HttpClientWrapper wrapper = (HttpClientWrapper) f1.get(twitter);
        final Field f2 = HttpClientWrapper.class.getDeclaredField("http");
        f2.setAccessible(true);
        
        // http = wrapper.http
        final twitter4j.internal.http.alternative.HttpClientImpl http = 
                (twitter4j.internal.http.alternative.HttpClientImpl) f2.get(wrapper);
        final Field f3 = http.getClass().getDeclaredField("client");
        f3.setAccessible(true);
        
        // client = http.client
        final OkHttpClient client = (OkHttpClient) f3.get(http);
        
        if (client != null) {
            final ConnectionPool p = client.getConnectionPool();
            message += "SPDY[" + p.getSpdyConnectionCount() + "], ";
            message += "HTTP[" + p.getHttpConnectionCount() + "])";
        } else {
            message += "no connections yet)";
        }
    } catch (Exception e) {
        Log.e(TAG, e.getMessage(), e);
    }
}
Log.d(TAG, message);

Twitter.getHomeTimeline() などを呼び出したあとに ConnectionPool.getSpdyConnectionCount() が1以上であれば正しくSPDY通信していると判定できます。

ちなみに TwitterFactory.getInstance() で Twitter オブジェクトを作った単位でプールが共有されます。通信のたびに TwitterFactory.getInstance() していると SPDY の意味がないので注意が必要です。

あと上の例のように twitter4j.internal.http.alternative.HttpClientImpl.sPreferSpdy を false に設定することで SPDY 通信を強制的にオフにすることが出来ます。これで、SPDY通信をオプション化することができます(拙作のTwitPaneでSPDY切替をするためにこの仕組みを入れました)。

ちなみに OkHttp なら・・・

Twitter4J ではなく OkHttp 自体を使う場合は (OkHttpClient.open で取得した) HttpURLConnection でレスポンスヘッダー見れば下記のようなカスタムヘッダーが取れるので判定できます。

OkHttp-Received-Millis:[1388254484917]
OkHttp-Response-Source:[NETWORK 200]
OkHttp-Selected-Transport:[http/1.1]
OkHttp-Sent-Millis:[1388254484817]