Можно ли очень быстро вызывать метод POST в TIndyHTTP несколько раз? - PullRequest
0 голосов
/ 09 мая 2019

Я использую Indy ver 10.5498, чтобы опубликовать некоторые данные из нескольких частей / форм, включая прикрепленный файл в API.Мой код адаптирован из кода, предоставленного мне Реми в этом сообщении, с обработкой ошибок протокола, взятой из здесь .Код, который у меня сейчас есть, работает хорошо, и я получаю ответ от сервера с данными примерно через 2 секунды после создания сообщения.

Однако иногда мне может понадобиться сделать сообщение несколько раз очень быстро, напримерперебирая набор данных, возвращенный из базы данных, и делая запись для каждой записи.

Есть ли что-то, что мне нужно знать, или какой-либо специальный код, который мне нужно написать, чтобы справиться с ситуацией, когда я мог бы сделать второй POST до того, как первый POST завершил отправку (или, по крайней мере, до того, как серверответ получен? Или это POST блокирующий вызов, который не возвращает управление, пока ответ не получен?

В данный момент компонент TIdHTTP помещается в форму, а не создается динамически. Я мог бы создать новыйTIdHTTP объект для каждого поста и уничтожить его впоследствии, если это необходимо.

Код, который я использую для поста в данный момент, находится ниже

function TForm1.Upload(url: string; params, filenames: TStrings): string;
var
 FormData : TIdMultiPartFormDataStream;
 ResponseText : string;
 i : integer;
begin
  FormData := TIdMultiPartFormDataStream.Create;
  try
    for i := 0 to params.Count - 1 do
      FormData.AddFormField(params.Names[i], params.ValueFromIndex[i]);
    for i := 0 to filenames.Count - 1 do
       FormData.AddFile('attachment', filenames[i]);   

    //add authorisation header
    IdHTTP1.Request.CustomHeaders.Add('Authorization:Basic ' + U_generalStuff.base64encodeStr(ATHORISATION_STR));

    //way to use just one try except yet get the full text server response whether its a 400 error or a success response
    //see https://stackoverflow.com/questions/54475319/accessing-json-data-after-indy-post
    // Make sure it uses HTTP 1.1, not 1.0,  and disable EIdHTTPProtocolException on errors
    IdHTTP1.ProtocolVersion := pv1_1;
    IdHTTP1.HTTPOptions := IdHTTP1.HTTPOptions + [hoKeepOrigProtocol, hoNoProtocolErrorException, hoWantProtocolErrorContent];
    try
       ResponseText := IdHTTP1.Post(url, FormData);   //post to the api
    except
      on E: Exception do
         begin
         ResponseText := E.ClassName + ': ' + E.message;
         raise;
         end;
    end; //try-except
  finally
     result := ResponseText;
  end; //try finally
end;

С тех пор я видел этосообщение , в котором говорится о многопоточности и использовании параллельной библиотеки. Это то, что я должен исследовать, чтобы ответить на мой вопрос?

1 Ответ

1 голос
/ 10 мая 2019

Как и большинство вещей в Indy, TIdHTTP.Post() - это синхронная операция.Он не возвращается обратно к вызывающей стороне, пока ответ не будет получен полностью (или пока не произойдет ошибка).Таким образом, если вы вызываете TIdHTTP.Post() в простом цикле, вы НЕ МОЖЕТЕ отправить новый запрос POST, пока предыдущий запрос не будет полностью завершен.Если вам нужно это сделать, вам придется вызывать TIdHTTP.Post() асинхронно , вызывая его в нескольких рабочих потоках (и назначать каждому потоку свой собственный объект TIdHTTP, так как вы не можете повторно использовать TIdHTTP объект для нескольких одновременных запросов).

...