Indy idHttp死机 - 如何使用keep-alive?
问题描述:
我开发了一个使用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
吗?还有什么我需要做的?
谢谢
答
您不需要在服务器端手动管理keepalive。 TIdHTTPServer
为您处理。只需将TIdHTTPServer.KeepAlive
属性设置为True(默认情况下为False,并且代码将其设置为False),并且完全不设置AResponseInfo.CloseConnection
属性。 TIdHTTPServer在发起OnCommandGet
事件之前,根据每个请求决定将其设置为什么值。
OK,但是客户端代码好吗?我做对了吗?你有任何想法为什么请求挂起?请求是否因服务器代码中的错误而挂起? –
你的客户端代码没问题(虽然我会删除'ReuseSocket'属性的使用)。您只需调试TIdHTTP的内部代码即可找到悬挂实际发生的位置。您还应该运行一个数据包嗅探器,以确保服务器实际上在挂起开始时发送数据回到客户端。 –
我不知道我是否有这个权利。服务器是否随时将数据发送回客户端?我从来没有见过这种情况。 –