簡體   English   中英

使用 okhttp3 發出多個異步 HTTP 2.0 請求

[英]Making multiple asynchronous HTTP 2.0 requests with okhttp3

我正在嘗試使用 okhttp (3.4.1) 來實現基於 HTTP 2.0 的客戶端。 我的部分要求是使用回調實現對不同 URL 的多個異步 HTTP 請求,以便稍后處理響應。 但是,在我當前的實現中,我發現我無法讓所有異步請求都使用相同的 TCP 連接,除非我在開​​始時從主線程發出阻塞 HTTP 請求。 我知道用於異步調用的 enque() 方法會使用調度程序,它似乎為每個請求生成一個新線程。 這是我的代碼片段:

    OkHttpClient client = new OkHttpClient();

我的異步獲取請求方法如下所示:

public void AsyncGet(String url) throws Exception {

    Request request = new Request.Builder().url(url).build();

    Call call = client.newCall(request);

    call.enqueue(new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {
            e.printStackTrace();
        }

        @Override
        public void onResponse(Call call, Response response) throws IOException {
            if (!response.isSuccessful()) {
                throw new IOException("Unexpected code " + response);
            }
            new Thread() {
                @Override
                public void run() {
                    /* Some code */
                }
            }.start();
        }
    });

}

我的同步Get請求如下:

public Response SyncGet(String url) throws Exception {

    Request request = new Request.Builder().url(url).build();

    Call call = client.newCall(request);
    Response response = call.execute();

    if (!response.isSuccessful()) {
        throw new IOException("Unexpected code " + response);
    }

    return response;
}

進行如下調用序列會觸發到服務器的 2 個 TCP 連接。

AsyncGet(Url);
AsyncGet(Url2);

但是,如下所示的調用序列使用相同的 TCP 連接。

SyncGet(Url);
AsyncGet(Url);
AsyncGet(Url2);

我還沒有調試過這個,但是看起來 OkHttp 迫使我們首先在主線程上發出一個阻塞的 HTTP 請求,以便可能獲得 TCP 連接上下文,然后與其他線程共享它? 或者,我錯過了什么?

您可以稍后根據可以區分呼叫響應的扇區來調用異步並將扇區設置為每個呼叫。 試試這個代碼; 我希望它會幫助你!

為 api 調用創建一個單獨的類:

public class RestApi {

    protected RestApiResponse serverResponse;
    protected Context c;

    public RestApi(RestApiResponse serverResponse, Context c) {
        this.serverResponse = serverResponse;
        this.c = c;
    }

    public void postDataWithoutAuth(String url,String sector) {


        OkHttpClient client = new OkHttpClient();

        Request request = new Request.Builder()
    .url("http://publicobject.com/helloworld.txt")
    .build();

        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.e("response", call.request().body().toString());
                serverResponse.onErrorLoaded(call.request().body().toString(), sector);
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                serverResponse.onResponseLoaded(response, sector);
            }


        });
    }
}

然后創建一個回調接口

public interface RestApiResponse {

    public void onResponseLoaded(Response response, String sector);

    public void onErrorLoaded(String response, String sector);
} 

並像這樣從您的活動中訪問它

RestApi apicall = new RestApi(this, getBaseContext());
apicall.postDataWithoutAuthUrlEncoded("ur url","your sector");

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM