【问题标题】:Indy idHttp freezes - How to work with keep-alive?Indy idHttp 冻结 - 如何使用 keep-alive?
【发布时间】:2012-01-09 03:37:57
【问题描述】:

我开发了一个使用 idHttpServer 的 Web 服务器和一个使用 idHTTP 的客户端应用程序。

我正在使用 Delphi 2010 和来自 trunk 的最新 indy svn 源代码。

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

所以,我需要知道如何在 indy 中正确使用 keep-alive。

到目前为止,我有这个代码:

在客户端:

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;

我做得对吗?什么可能导致客户端应用程序冻结并且不完成发布请求?

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

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

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

客户端应用程序没有冻结,一切正常。

在向服务器发送请求之前我应该​​清除IOHandler.InputBuffer 吗?我还有什么需要做的吗?

谢谢

【问题讨论】:

    标签: delphi sockets delphi-2010 indy


    【解决方案1】:

    您不需要在服务器端手动管理保活。 TIdHTTPServer 为您处理。只需将TIdHTTPServer.KeepAlive 属性设置为True(默认为False,并且您的代码将其设置为False)并且根本不设置AResponseInfo.CloseConnection 属性。 TIdHTTPServer 在触发OnCommandGet 事件之前根据每个请求决定将其设置为什么值。

    【讨论】:

    • 可以,但是客户端代码可以吗?我做对了吗?您知道为什么请求会挂起吗?请求挂起是因为我在服务器代码上的错误吗?
    • 您的客户端代码很好(尽管我会删除 ReuseSocket 属性的使用)。您只需调试 TIdHTTP 的内部代码即可找到实际发生挂起的位置。您还应该运行一个数据包嗅探器,以确保在挂起开始发生时服务器实际上正在将数据发送回客户端。
    • 我不确定我是否做对了。服务器是否随时将数据发送回客户端?我从未见过这种情况发生。
    • HTTP 使用命令/响应模型。默认情况下,TIdHTTPServer 在客户端首先向服务器发送请求之前不会向客户端发送任何内容。除非您通过直接访问连接来手动向客户端发送数据,例如,如果您尝试实现 HTTP 服务器推送模型 (en.wikipedia.org/wiki/Server_push#HTTP_server_push)。
    猜你喜欢
    • 2012-01-04
    • 2016-09-07
    • 1970-01-01
    • 2018-07-08
    • 2019-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-07
    相关资源
    最近更新 更多