Indy idHttp зависает - Как работать с keep-alive? - PullRequest
5 голосов
/ 29 ноября 2011

Я разработал веб-сервер, который использует idHttpServer, и клиентское приложение, которое использует idHTTP.

Я использую Delphi 2010 и последний indy svn source из транка.

Это приложение отправляет около 1000 запросов на веб-сервер в цикле. Из-за TIME_WAITS и накладных расходов на подключение к веб-серверу мне нужно использовать keep-alive. Проблема в том, что после выполнения около 700 запросов к серверу мое приложение (на стороне клиента) зависает почти на 10 минут при отправке данных на веб-сервер (что происходит почти каждый раз).

Итак, мне нужно знать, как правильно использовать keep-alive с 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;

Я правильно делаю? Что может быть причиной того, что клиентское приложение зависло и не завершило почтовый запрос?

Я пытался отладить сервер, когда клиент зависает, но метод OnClientRead не запускается. Мне кажется, что у клиента возникают проблемы при попытке подключиться к веб-серверу.

Если я изменю код клиента на:

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

Клиентское приложение не зависает и все работает хорошо.

Должен ли я очистить IOHandler.InputBuffer перед отправкой запроса на сервер? Есть ли что-нибудь еще, что мне нужно сделать?

Спасибо

1 Ответ

9 голосов
/ 30 ноября 2011

Вам не нужно управлять средствами поддержки активности вручную на стороне сервера. TIdHTTPServer справится с этим для вас. Просто установите для свойства TIdHTTPServer.KeepAlive значение True (по умолчанию это False, а ваш код в любом случае устанавливает значение False) и вообще не устанавливайте свойство AResponseInfo.CloseConnection. TIdHTTPServer решает, какое значение установить для каждого запроса, до запуска события OnCommandGet.

...