2014-05-14 126 views
0

我正在使用HttpClient向遠程Web服務器發送異步POST請求。該遠程Web服務器響應Connection標頭設置爲keep-alive。最終,它會關閉連接。如何在保持活動狀態的HttpResponseMessage關閉前收聽?

什麼我不知道該怎麼辦是保持接收數據,直到連接設置爲關閉。

例如,考慮下面的代碼:

HttpClient client = new HttpClient(); 
string requestUri = ...; //My GET uri 
string content = ...; //url-encoded contents of the request 

HttpResponseMessage response = await client.PostAsync(requestUri, new StringContent(content)); 

在上面的代碼,response將具有Connection頭設置爲keep-alive。我找不到HttpResponseMessage上的任何會員,在收到第一個keep-alive之後,我似乎都會繼續收到信息。

我不知道如何繼續接收響應,直到Connection關閉。

我能找到處理髮送keep-alive請求的各種資源。這不是我的問題。我的問題是在接收/處理來自服務器的keep-alive響應。

請讓我知道是否有任何我可以提供的信息來改善這個問題。

+1

不知道我是否誤解了你的問題,但是一旦你發佈了請求並獲得了響應,週期(請求/響應)就完成了,沒有更多的數據從服務器接收。 – ManyRootsofAllEvil

+0

@ManyRootsofAllEvil你說的是真的。如果服務器以「Connection:keep-alive」響應,這意味着服務器到客戶端的連接尚未關閉。我需要繼續接收響應,直到連接關閉。 – crush

+0

@crush你是說你收到原始請求的部分回覆?還是你問如何接收來自相同連接的連續請求的響應? – LB2

回答

2

Connection: keep-alive目的不是爲了讓服務器針對同一個請求發送多個響應 - 這將從根本上違反HTTP的工作方式。

Connection: keep-alive是服務器向客戶端發信號通知客戶端可以使用相同的,已建立的TCP連接提交下一個請求的方式,從而有助於避免建立新連接(以及可能的TLS握手)的成本。

連接的重用(通常)是由底層庫處理的,並且被抽象出來,使得庫的用戶(如開發人員)無需擔心處理。

所有你應該做的就是不斷做出多少client.Post/Get/etc請求,而HttpClient庫將負責管理底層TCP連接及其重用。

HTTP中有一個區域可能看起來與上述相反並因此而混淆,但不是。這種情況是當服務器返回HTTP狀態100 Continue。在這種情況下,您將看到另一個來自服務器的響應,它仍然是相同的原始請求(「請參閱」我的意思不是來自HttpClient,而是如果您要使用WireShark或代理等工具進行窺探)。在這種情況下發生的事情是,如果客戶端發出大量請求,則服務器只是向客戶端發送信號,表明它正在繼續接受和讀取請求,並且客戶端繼續發送該原始請求。收到完整請求後,服務器將處理並以最終響應代碼和消息進行響應。再次,HttpClient將抽象出這個臨時100 Continue響應,因此開發人員不必擔心(大多數情況下,如果不是全部情況)。

+0

感謝您的解釋。這個問題源自對Keep-Alive的誤解和對我的監督。 – crush

+0

@crush謝謝,我更新了有關狀態代碼'100'的其他怪癖的答案,這可能與答案所示相反,但事實上並非如此。 – LB2

+0

非常酷。感謝那些附加信息。我總是想知道引擎蓋下發生了什麼。 – crush

1

如果您只想收到針對給定請求的響應,則根本不需要處理保持活動狀態。保持活力純粹是性能優化。該框架透明地管理連接。

您所要做的就是發送請求並收到回覆。每個請求只有一個響應。

一方最終會關閉你不關心的連接。你沒有注意到這種影響。

+0

謝謝。這有助於消除我對Keep-Alive重要性的誤解。 – crush