2011-11-29 65 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

我不知道我是否有这个权利。服务器是否随时将数据发送回客户端?我从来没有见过这种情况。 –