2011-11-29 219 views
4

我開發了一個使用idHttpServer一個Web服務器和使用idHTTP客戶端應用程序。Indy idHttp死機 - 如何使用keep-alive?

我使用德爾福2010年從主幹上的最新印SVN源。

此應用程序發送一個循環大約1000個請求的Web服務器。由於TIME_WAITS和連接到網絡服務器的開銷,我需要使用keep-alive。問題是:向服務器發出大約700次請求之後,我的應用程序(客戶端)在將數據發佈到Web服務器(幾乎每次都發生)時掛起將近10分鐘。

所以,我需要知道如何正確使用保活用印。

到目前爲止,我有這樣的代碼:

在客戶端:

oIndyHttpClient := TIdHTTP.Create(nil); 
oIndyHttpClient.ProxyParams.Clear; 
oIndyHttpClient.Request.CacheControl := 'no-cache'; 
oIndyHttpClient.ProtocolVersion := pv1_1; 
oIndyHttpClient.HTTPOptions := oIndyHttpClient.HTTPOptions + [hoKeepOrigProtocol]; 
oIndyHttpClient.ReuseSocket := rsOSDependent; 
oIndyHttpClient.Request.Connection := 'keep-alive'; 

和服務器端:

oIdHttpServer.OnCommandGet := Self.OnClientRead; 
oIdHttpServer.AutoStartSession := False; 
oIdHttpServer.KeepAlive := False; 

procedure TPLKWSServerSocketIndy.OnClientRead(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo); 
begin 
    //do some stuff here 
    if LowerCase(ARequestInfo.Connection) = 'keep-alive' then begin 
    AResponseInfo.CloseConnection := False; 
    end 
    else begin 
    AResponseInfo.CloseConnection := True; 
    end; 
end; 

我這樣做對嗎?什麼可能導致客戶端應用程序凍結並不完成發佈請求?

我試圖做調試服務器時,客戶端凍結,但OnClientRead方法不被解僱。在我看來,客戶端在嘗試連接網絡服務器時遇到了問題。

如果我修改客戶端代碼:

oIndyHttpClient.ProtocolVersion := pv1_0; 
oIndyHttpClient.Request.Connection := 'close'; 

的客戶端應用程序也不會凍結,一切工作良好。

在向服務器發送請求之前,我應該清除IOHandler.InputBuffer嗎?還有什麼我需要做的?

謝謝

回答

7

您不需要在服務器端手動管理keepalive。 TIdHTTPServer爲您處理。只需將TIdHTTPServer.KeepAlive屬性設置爲True(默認情況下爲False,並且代碼將其設置爲False),並且完全不設置AResponseInfo.CloseConnection屬性。 TIdHTTPServer在發起OnCommandGet事件之前,根據每個請求決定將其設置爲什麼值。

+0

OK,但是客戶端代碼好嗎?我做對了嗎?你有任何想法爲什麼請求掛起?請求是否因服務器代碼中的錯誤而掛起? –

+0

你的客戶端代碼沒問題(雖然我會刪除'ReuseSocket'屬性的使用)。您只需調試TIdHTTP的內部代碼即可找到懸掛實際發生的位置。您還應該運行一個數據包嗅探器,以確保服務器實際上在掛起開始時發送數據回到客戶端。 –

+0

我不知道我是否有這個權利。服務器是否隨時將數據發送回客戶端?我從來沒有見過這種情況。 –