Indy idHttp冻结-如何使用持久连接?

5
我开发了一个Web服务器,它使用idHttpServer,客户端应用程序使用idHTTP

我正在使用Delphi 2010和最新的indy svn源自干线。

该应用程序在循环中向Web服务器发送约1000个请求。由于TIME_WAITS和连接到Web服务器的开销,我需要使用keep-alive。问题是:向服务器发出大约700个请求后,我的应用程序(客户端)在发布数据到Web服务器时会挂起近10分钟(几乎每次都会发生)。

所以,我需要知道如何正确地使用indy进行持续连接。

到目前为止,我有以下代码:

客户端代码:

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;

我做得对吗?是什么导致客户端应用程序冻结并无法完成POST请求呢?

当客户端冻结时,我尝试调试服务器,但 OnClientRead 方法没有被触发。在我看来,客户端尝试连接Web服务器时遇到了问题。

如果我修改客户端代码为:

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

客户端应用程序不会冻结,一切都运行良好。
在向服务器发送请求之前,我是否应该清除IOHandler.InputBuffer?还有其他需要注意的事项吗?
谢谢。
1个回答

9
您无需在服务器端手动管理keep-alive。 TIdHTTPServer 会为您处理这些事务。只需将TIdHTTPServer.KeepAlive属性设置为True(默认为False,而您的代码无论如何都将其设置为False),并且根本不设置AResponseInfo.CloseConnection属性。 TIdHTTPServer在触发OnCommandGet事件之前,会基于每个请求决定要设置的值。

好的,但客户端代码没问题吗?我做得对吗?你有任何想法为什么请求会挂起吗?是因为我在服务器代码上犯了错误导致请求挂起吗? - Rafael Colucci
你的客户端代码没问题(虽然我建议删除ReuseSocket属性的使用)。你需要调试TIdHTTP的内部代码,找到实际发生挂起的地方。同时,你应该运行数据包嗅探器,确保在挂起开始出现时服务器确实向客户端发送数据。 - Remy Lebeau
我不确定我是否理解正确。服务器是否会随时向客户端发送数据?我从未见过这种情况发生。 - Rafael Colucci
HTTP使用命令/响应模型。默认情况下,TIdHTTPServer不会向客户端发送任何内容,直到客户端首先向服务器发送请求。除非您通过直接访问连接手动向客户端发送数据,例如如果您正在尝试实现HTTP服务器推送模型(http://en.wikipedia.org/wiki/Server_push#HTTP_server_push)。 - Remy Lebeau

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接