簡體   English   中英

在響應完成之前關閉HttpURLConnection

[英]Closing an HttpURLConnection before the response is complete

背景

我在客戶端使用HttpURLConnection在HTTP流(服務器推送)情況下使用響應。 雖然服務器可以通過關閉響應來關閉連接,但客戶端也需要能夠執行此操作。

問題

客戶端在單獨的線程中處理InputStream ,如下所示:

@Override
public void run() {
    try {
        for (int b = in.read(); b >= 0; b = in.read()) {
            char c = (char) b;
            // Do something with the character
            // ...
        }
    }
    catch (IOException e) {
    }
}

因此,當我從發起連接的線程調用HttpURLConnection.disconnect() (重要的信息是它與處理輸入的線程不同),該調用將無限期掛起。 我甚至把它留在了一夜之間它仍然懸掛着。 即使調用Thread.interrupt()也無濟於事。

建議?

看起來如果不改變讀取線程使用InputStream.available()進行輪詢,並且在沒有可用字節的情況下休眠一段短的perdiod,一直檢查一些標志以查看線程是否應該結束。

解決方案是僅使用Apache HTTP組件。 通過將GET請求的代碼封裝在一個類中,可以很容易地將其集成到現有代碼中。

public class HttpGetConnection implements AutoCloseable {
    public HttpGetConnection(String url) throws IOException {
        client = new DefaultHttpClient();
        get = new HttpGet(url);
        response = client.execute(get);
        entity = response.getEntity();
    }

    public InputStream getContent() throws IOException {
        content = entity.getContent();
        return content;
    }

    @Override
    public void close() throws Exception {
        get.abort();
        try {
            content.close();
        }
        catch (IOException e) {
        }
    }

    private HttpClient client;
    private HttpGet get;
    private HttpResponse response;
    private HttpEntity entity;
    private InputStream content;
}

原始帖子中的循環可以保持原樣,並且在調用HttpGetConnection.close()之后,讀取線程將很快死亡。

如果服務器沒有關閉連接但停止發送數據, in.read()將阻止。 現在,請注意HttpURLConnection.HttpInputStream.close()的代碼也將嘗試從流中讀取以確定到達流的末尾( 源代碼) 反過來, close()disconnect()調用。 最終你的線程被阻止了。

所以你似乎需要改變你的邏輯。 我假設您根據某些條件關閉連接。 因此,在讀取線程中讀取下一個字節之前,不要在不同的線程中檢查條件,然后斷開連接。

順便說一句, Thread.interrupt()不會幫助你,因為它只會在你的等待IO時中斷在監視器上等待的線程。

另一種解決方法是將輸入流包裝在Channel中並使用它( Channels.newChannel ),如JDK-4329256的變通方法中所建議的那樣 這將導致在線程中斷時關閉底層輸入流。 但是,JDK中有一條評論說它不是真正可以中斷的。 在我的測試中它似乎工作。 我在這里要求了解更多信息。

暫無
暫無

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

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