天天看點

chromium-cronet庫的編譯用于Android和ios平台實作quic協定 

chromium-cronet文檔 原文文檔寫的已經很清楚,最好還是參考官方文檔,避免由于版本原因導緻的問題。

Cronet開發者文檔:https://developer.android.com/guide/topics/connectivity/cronet

部落格中的git位址:https://github.com/bgylde/chromium-cornet

環境配置

  1. chromium源碼環境;
  2. 已經配置好相關環境,安裝好相關依賴;
  3. 這裡是在linux環境下對Android庫的編譯,在macos環境下會直接編譯為ios平台庫;

編譯開發和debug環境的Cronet庫

Android / IOS build

$ ./components/cronet/tools/cr_cronet.py gn --out_dir=out/Cronet
           

如果build主機是在linux環境下,build的是android的庫。如果build主機是macOS,build的是ios庫。

$ ninja -C out/Cronet cronet_package
           

編譯Cronet庫,最終檔案可以在out/Cronet/cornet中尋找。

使用cronet庫

  1. 建立CronetEngine,最好整個應用使用一個CronetEngine,這裡可以了解為OkHttpClient;
  2. 建立自己的線程池給Cronet使用,Cronet的網絡請求都會線上程池中,避免主線程阻塞;
  3. 實作回調UrlRequest.Callback,在UrlRequest調用start以後,網絡請求開始,之後産生請求回調;
public class UrlRequestCallback extends UrlRequest.Callback {

    private static final String TAG = "UrlRequestCallback";

    private long startTime;
    private ByteBuffer mByteBuffer = ByteBuffer.allocateDirect(102400);
    private ByteArrayOutputStream mBytesReceived = new ByteArrayOutputStream();
    private WritableByteChannel mReceiveChannel = Channels.newChannel(mBytesReceived);

    @Override
    public void onRedirectReceived(UrlRequest request, UrlResponseInfo info, String newLocationUrl) {
        LogUtils.i(TAG, "onRedirectReceived method called.");
        // You should call the request.followRedirect() method to continue
        // processing the request.
        request.followRedirect();
    }

    @Override
    public void onResponseStarted(UrlRequest request, UrlResponseInfo info) {
        LogUtils.i(TAG, "onResponseStarted method called.");
        // You should call the request.read() method before the request can be
        // further processed. The following instruction provides a ByteBuffer object
        // with a capacity of 102400 bytes to the read() method.
        //ByteBuffer byteBuffer = ByteBuffer.allocateDirect(102400);
        startTime = System.currentTimeMillis();
        request.read(mByteBuffer);
    }

    @Override
    public void onReadCompleted(UrlRequest request, UrlResponseInfo info, ByteBuffer byteBuffer) {
        LogUtils.i(TAG, "onReadCompleted method called.");
        // You should keep reading the request until there's no more data.

        try {
            byteBuffer.flip();
            mReceiveChannel.write(byteBuffer);
            byteBuffer.clear();
        } catch (IOException e) {
            LogUtils.e(TAG, e);
        }

        request.read(mByteBuffer);
    }

    @Override
    public void onSucceeded(UrlRequest request, UrlResponseInfo info) {
        LogUtils.i(TAG, "onSucceeded method called: " + info.toString());
        LogUtils.d(TAG, "cost time: " + (System.currentTimeMillis() - startTime) + " ms");
        //byte[] bytes = mBytesReceived.toByteArray();
        String receivedData = null;
        try {
            receivedData = mBytesReceived.toString("GBK");
        } catch (UnsupportedEncodingException e) {
            LogUtils.e(TAG, e);
        }

        final String url = info.getUrl();
        final String text = "Completed " + url + " (" + info.getHttpStatusCode() + ")";
        //LogUtils.i(TAG, "text: " + text);
        //LogUtils.i(TAG, "receivedData: " + receivedData);
    }

    @Override
    public void onFailed(UrlRequest urlRequest, UrlResponseInfo urlResponseInfo, CronetException e) {
        //LogUtils.d(TAG, "url: " + urlResponseInfo.getUrl());
        LogUtils.e(TAG, "onFailed method called.", e);
    }

    @Override
    public void onCanceled(UrlRequest request, UrlResponseInfo info) {
        LogUtils.d(TAG, "onCanceled method called.");
    }
}
           
  • onRedirectReceived 顧名思義,是重定向的回調,這裡直接選擇繼續通路重定向的位址,也可以調用UrlRequest的cancel方法,取消通路;
  • onResponseStarted 從google文檔上面來看是請求完header以後開始請求body部分會回調這裡,每次請求隻會回調一次;
  • onReadCompleted 這是讀取body一定資料時會回調這個方法,這裡request.read讀取的資料不一定會填滿緩沖區,請求生命周期中會有多次回調發生;
  • onSucceeded 最終請求成功回調,可以作為資料處理階段;
  • onFailed 請求失敗回調,例如網絡不通,或者沒有網絡通路權限之類的錯誤;
  • onCanceled 請求取消回調,隻會在cancel後才會回調,回調這個意味着整個請求完成;
https://ssl.gstatic.com/gb/images/qi2_00ed8ca1.png 實作quic通路,可作為測試位址。

 這是通過抓包看到的quic協定,進一步的性能對比就需要自己搭建一個支援quic協定的伺服器。

chromium-cronet庫的編譯用于Android和ios平台實作quic協定