Indy idHttp 冻结 - 如何使用 keep-alive?

发布于 2024-12-18 15:44:09 字数 1624 浏览 2 评论 0原文

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

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

该应用程序循环发送大约 1000 个请求到 Web 服务器。由于 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;

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

我尝试在客户端冻结时调试服务器,但是 OnClientRead 方法不会被触发。在我看来,客户端在尝试连接网络服务器时遇到问题。

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

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

客户端应用程序不会冻结并且一切正常。

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

谢谢

I developed a Webserver that uses idHttpServer and a client application that uses idHTTP.

I am using Delphi 2010 and the latest indy svn source from trunk.

This application sends about 1000 requests to the Web Server in a loop. Because of TIME_WAITS and the overhead of connecting to a webserver, I need to use keep-alive. The problem is: after making about 700 requests to the server, my application (the client side) hangs for almost 10 minutes when posting data to the webserver (that happens almost every time).

So, I need to know how to properly use keep-alive with indy.

So far I have this code:

On the client side:

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';

And on the server side:

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;

Am i doing it right? What can be causing the client application do freeze and do not complete the post request?

I tried do debug the server when the client freezes, but the OnClientReadmethod does not get fired. It seems to me that the client is having issues trying to connect do the web server.

If I modify the client code to:

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

The client app does not freeze and everything works nice.

Should I clear IOHandler.InputBuffer before sending a request to the server? Is there anything else I need to do?

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

后来的我们 2024-12-25 15:44:09

您不需要在服务器端手动管理保持活动。 TIdHTTPServer 会为您处理这个问题。只需将 TIdHTTPServer.KeepAlive 属性设置为 True(默认情况下为 False,并且您的代码无论如何都将其设置为 False),并且不要在以下位置设置 AResponseInfo.CloseConnection 属性:全部。 TIdHTTPServer 在触发 OnCommandGet 事件之前,根据每个请求决定将其设置为什么值。

You do not need to manage keep-alives manually on the server side. TIdHTTPServer handles that for you. Simply set the TIdHTTPServer.KeepAlive property to True (it is False by default, and your code is setting it to False anyway) and do not set the AResponseInfo.CloseConnection property at all. TIdHTTPServer decides what value to set it to, on a per-request basis, before firing the OnCommandGet event.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文