Я использую Indy 10.5.9.0.
Это очень старая и устаревшая версия. На момент написания этой статьи последняя версия - 10.6.2.5455. Пожалуйста, обновите , так как было много изменений и исправлений в Indy с 10.5.9.
Когда я вызываю метод TIdHTTP.Post()
, компонент зависает и вызывает исключение:
Во-первых, вы не звоните TIdHTTP.Post()
, вы звоните TIdHTTP.DoRequest()
. Вместо этого вы должны звонить TIdHTTP.Post()
, что для вас вызывает TIdHTTP.DoRequest()
:
httpClient.Post(srv, JsonToSend, jsonRetorno);
Во-вторых, Post()
не может замерзнуть и вызвать исключение одновременно. Что на самом деле происходит? Насколько велик JSON, который вы публикуете? Отправляет ли сервер какой-либо ответ до возникновения исключения?
В-третьих, вы абсолютно НЕ должны вообще звонить TIdHTTP.SetRequestParams()
. Этот метод предназначен для внутреннего использования перегруженной версией TStrings
TIdHTTP.Post()
, когда он отправляет веб-форму HTML в формате application/x-www-webform-urlencoded
. Это НЕ то, что вам нужно в этой ситуации. Вы должны опубликовать свой JSON как есть, а не кодировать его в веб-форме.
Indy использует блокирующие сокеты. Большинство операций в Indy являются синхронными. TIdHTTP.Post()
ничем не отличается. Он блокирует вызывающий поток до тех пор, пока сообщение HTTP не будет завершено Если он зависает, это означает, что отправка сообщения занимает много времени или сервер не отправляет верный ответ. Если TIdHTTP.Post()
вызывает исключение «Соединение закрыто изящно», это означает, что сервер закрыл соединение с сокетом на своем конце, в то время как TIdHTTP
все еще отправлял / считывал данные через сокет. Это может произойти, например, если серверу не нравится ваш запрос POST
или если он определяет, что JSON недействителен во время его получения.
Кроме того, ваш код может быть упрощен в целом. Вы неправильно используете TStringList
для обработки данных JSON.
Попробуйте вместо этого что-нибудь более похожее:
var
sJSON, sRetorno: string;
jsonLatestFirmware: TJSONValue;
JsonToSend: TStringStream;
...
begin
...
try
sJSON := httpClient.Get(strGetLatest);
except
ShowMessage('There are no firmwares available for this product.');
Exit;
end;
try
jsonLatestFirmware := TJSONObject.ParseJSONValue(sJSON);
try
sJson := (jsonLatestFirmware as TJSONObject).get('data').JsonValue.ToString;
finally
jsonLatestFirmware.Free;
end;
JsonToSend := TStringStream.Create(sJson, TEncoding.UTF8);
try
JsonToSend.SaveToFile(ExtractFilePath(Application.ExeName) + 'finals\' + currentMACQR + '-' + currentAlive.IP + '.json');
httpClient.Request.ContentType := 'application/json';
sRetorno := httpClient.Post('http://' + currentAlive.IP + ':9335/upgrade?command=start', JsonToSend);
finally
JsonToSend.Free;
end;
except
on E: Exception do
ShowMessage('Error: '#13#10 + E.Message);
Exit;
end;
lblInformacao.Visible := True;
ShowMessage(sRetorno);
...
end;