[РЕШЕНО]Ошибка инициализации SSL в TFPHTTPClient в потоке

Общие вопросы программирования, алгоритмы и т.п.

Модератор: Модераторы

[РЕШЕНО]Ошибка инициализации SSL в TFPHTTPClient в потоке

Сообщение yus » 04.04.2018 16:16:57

Добрый день.

Столкнулся с такой проблемой.
Имеется класс наследник от TThread в нем происходит обращение к https узлу.
В основном теле создаю несколько потоков в которых идет обращения на https узлы.
Когда поток один то все работает замечательно, когда запускаю одновременно несколько потоков то первый поток запускается успешно а в последующих возникает ошибка
Project project1 raised exception class 'EInOutError' with message:
Could not initialize OpenSSL library


Вот простейший код который воспроизводит эту ошибку.
Код: Выделить всё
program project1;

uses
  unit1;

var
  MYThread: array[0..2] of TMyHTTPRequest;
  i: integer;
begin
  for i := 0 to 2 do
  begin
    MYThread[i] := TMyHTTPRequest.Create(True);
    MYThread[i].FreeOnTerminate := True;
    MYThread[i].Start;
  end;
  ReadLn;
end.         


Код: Выделить всё
unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, fphttpclient, sslsockets, fpopenssl;

type

  { TMyHTTPRequest }

  TMyHTTPRequest = class(TThread)
  public
    procedure Execute; override;
  end;

implementation

{ TMyHTTPRequest }

procedure TMyHTTPRequest.Execute;
var
  Client: TFPHTTPClient;
  res: string;
begin
  Client := TFPHTTPClient.Create(nil);
  res := Client.Get('https://google.com');
  FreeAndNil(Client);
end;

end.


Что я делаю не так и как победить?
Спасибо.
Последний раз редактировалось yus 05.04.2018 01:55:18, всего редактировалось 3 раз(а).
yus
новенький
 
Сообщения: 27
Зарегистрирован: 29.03.2015 14:29:29
Откуда: Москва

Re: Ошибка SSL в TFPHTTPClient при работе в потоке

Сообщение vitaly_l » 04.04.2018 16:26:00

yus писал(а): 
for i := 0 to 2 do
  begin
    MYThread := TMyHTTPRequest.Create(True);

Вы создали MYThread и потом снова его создаёте.
Сделайте var MYThread array [0..2] of TMyHTTPRequest;
и потом создавайте MYThread[i] := TMyHTTPRequest.Create(True);
Аватара пользователя
vitaly_l
долгожитель
 
Сообщения: 3333
Зарегистрирован: 31.01.2012 16:41:41

Re: Ошибка SSL в TFPHTTPClient при работе в потоке

Сообщение yus » 04.04.2018 16:35:49

vitaly_l писал(а):
yus писал(а): 
for i := 0 to 2 do
  begin
    MYThread := TMyHTTPRequest.Create(True);

Вы создали MYThread и потом снова его создаёте.
Сделайте var MYThread array [0..2] of TMyHTTPRequest;
и потом создавайте MYThread[i] := TMyHTTPRequest.Create(True);

К сожалению это не решает проблему.

PS: подредактировал код
yus
новенький
 
Сообщения: 27
Зарегистрирован: 29.03.2015 14:29:29
Откуда: Москва

Re: Ошибка инициализации SSL в TFPHTTPClient при работе в по

Сообщение Ichthyander » 04.04.2018 19:01:17

Да, странная ошибка. Использую многопоточное обращение по протоколу https, но таких проблем не наблюдал...

Добавлено спустя 8 минут 41 секунду:
Re: Ошибка инициализации SSL в TFPHTTPClient при работе в потоке
Можно было бы предположить, что у Вас не установлена библиотека или нет соответствующих DLL в папке, но первый поток, говорите, что без ошибокк. Это точно?
Аватара пользователя
Ichthyander
энтузиаст
 
Сообщения: 668
Зарегистрирован: 04.04.2007 08:32:43
Откуда: Астрахань

Re: Ошибка инициализации SSL в TFPHTTPClient при работе в по

Сообщение yus » 04.04.2018 19:20:00

Если сделать цикл от 0 до 0 то происходит запуск одного потока и он прекрасно отрабатывает.
yus
новенький
 
Сообщения: 27
Зарегистрирован: 29.03.2015 14:29:29
Откуда: Москва

Re: Ошибка инициализации SSL в TFPHTTPClient при работе в по

Сообщение pupsik » 04.04.2018 19:25:05

а если так:

Код: Выделить всё
program project1;

uses
  unit1,
  openssl;
.....
var
  MYThread: array[0..2] of TMyHTTPRequest;
  i: integer;
begin
  InitSSLInterface; 


Добавлено спустя 23 минуты 58 секунд:
Re: Ошибка инициализации SSL в TFPHTTPClient при работе в потоке
В принципе:

такое

Код: Выделить всё
program project1;

uses
  sysutils,
  Unit1,
  openssl,
  Math,
  fgl;

type
  TMYThread = specialize TFPGList<TMyHTTPRequest>;

  TURLTable = array[0..4] of string;

const
  URLTable : TURLTable = (
                          'https://google.com.ru/',
                          'https://translate.google.com.ru/',
                          'https://sourceforge.net',
                          {ну а чё? :)}
                          'http://www.freepascal.ru/',
                          'https://lenta.ru/'
                          );

var
  MYThread : TMYThread;
  tmp_arr  : TMyHTTPRequest;
  i, z, arr_c : integer;
  can_free : Boolean;

function GetUrl : string;
begin
  result := URLTable[Random(High(URLTable))];
end;

begin
  Randomize;
  InitSSLInterface;
  arr_c := 2;
  Write('Count: ');
  Read(arr_c);
  MYThread := TMYThread.Create;
  for i := 0 to arr_c - 1 do
  begin
    tmp_arr  := TMyHTTPRequest.Create(true);
    tmp_arr.URL := GetUrl;
    MYThread.Add(tmp_arr);
    MYThread.Items[i].Start;
  end;
  {не сильно верный вариант}
  can_free := false;
  While not can_free do
  begin
    z := 0;
    for i := 0 to arr_c - 1 do
    begin
      if MYThread.Items[i].Active then
        inc(z);
    end;
    if z = 0 then
      can_free := true;
    Sleep(2);
  end;
  MYThread.Clear;
  FreeAndNil(MYThread);
  WriteLn('End works');
end.


плюс такое
Код: Выделить всё
unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes,
  SysUtils,
  fphttpclient;

type

  { TMyHTTPRequest }

  TMyHTTPRequest = class(TThread)
  private
    Client    : TFPHTTPClient;
    fsteam    : TMemoryStream;
    f_url     : string;
    f_active  : Boolean;
  protected
    procedure Execute; override;
  public
    constructor Create(CreateSuspended : boolean);
    destructor Destroy; override;
    property URL : string write f_url;
    property Active : Boolean read f_active;
  end;

implementation

{ TMyHTTPRequest }

constructor TMyHTTPRequest.Create(CreateSuspended: boolean);
begin
  inherited Create(CreateSuspended);
  FreeOnTerminate := True;
  Client := TFPHTTPClient.Create(nil);
  fsteam := TMemoryStream.Create;
  With Client do
  begin
    HTTPversion := '1.1';
  end;
  f_active := true;
end;

procedure TMyHTTPRequest.Execute;
begin
  try
    try
      Client.HTTPMethod('GET', f_url, fsteam, [200, 301, 302])
    except
      on e : Exception do
        WriteLn(e.Message);
    end;
  finally
    WriteLn(Client.ResponseStatusCode, ' from url ', f_url);
  end;
  f_active := false;
end;


destructor TMyHTTPRequest.Destroy;
begin
  FreeAndNil(Client);
  FreeAndNil(fsteam);
  inherited Destroy;
end;
end.


шото там делает
Последний раз редактировалось pupsik 05.04.2018 09:49:34, всего редактировалось 1 раз.
pupsik
энтузиаст
 
Сообщения: 1154
Зарегистрирован: 20.08.2014 16:20:13

Re: Ошибка инициализации SSL в TFPHTTPClient при работе в по

Сообщение yus » 05.04.2018 01:50:00

pupsik писал(а):а если так:

Огромное спасибо мил человек :)
Вот решение!
Код: Выделить всё
InitSSLInterface;
yus
новенький
 
Сообщения: 27
Зарегистрирован: 29.03.2015 14:29:29
Откуда: Москва

Re: [РЕШЕНО]Ошибка инициализации SSL в TFPHTTPClient в поток

Сообщение Ichthyander » 05.04.2018 10:23:22

Теперь понятно, в моих приложениях вызывается модуль ssl_openssl, то есть в разделе Uses обязательно идет ссылка на него. А вот в разделе инциализации этого модуля есть вот это.
Код: Выделить всё
{==============================================================================}

initialization
  if InitSSLInterface then
    SSLImplementation := TSSLOpenSSL;
В результате чего необязательно инициировать InitSSLInterface

Добавлено спустя 2 минуты 9 секунд:
Re: [РЕШЕНО]Ошибка инициализации SSL в TFPHTTPClient в потоке
Хотя нет. Это же Synapse...

Добавлено спустя 8 минут 14 секунд:
Re: [РЕШЕНО]Ошибка инициализации SSL в TFPHTTPClient в потоке
А те же приложения, что используют fphttpclient: так там вообще нет ни ссылок на ssl_openssl, ни ссылок на sslsockets и fpopenssl, как в примере кода топикстартера, и, странно, но все соединения по HTTPS прекрасно работают :/

Добавлено спустя 55 секунд:
Re: [РЕШЕНО]Ошибка инициализации SSL в TFPHTTPClient в потоке
Но возможно дело в том, что это Debian и там OpenSSL автоматически подгружаются или типа того... Хотя в Windows 10 тоже работает прекрасно... Темный лес :)
Аватара пользователя
Ichthyander
энтузиаст
 
Сообщения: 668
Зарегистрирован: 04.04.2007 08:32:43
Откуда: Астрахань

Re: [РЕШЕНО]Ошибка инициализации SSL в TFPHTTPClient в поток

Сообщение wofs » 06.04.2018 12:08:05

Ichthyander
Использую fphttpclient и SSL. Все прекрасно работает. Ссылка на модуль OpenSSL есть в недрах fphttpclient.
Аватара пользователя
wofs
постоялец
 
Сообщения: 379
Зарегистрирован: 05.10.2009 10:16:55
Откуда: Астрахань

Re: [РЕШЕНО]Ошибка инициализации SSL в TFPHTTPClient в поток

Сообщение Ichthyander » 06.04.2018 15:17:44

wofs у меня тоже работает ;) Прочитайте еще раз. Я просто пытался понять, почему не работает у топикстартера без InitSSLInterface в многопоточном приложении.
Аватара пользователя
Ichthyander
энтузиаст
 
Сообщения: 668
Зарегистрирован: 04.04.2007 08:32:43
Откуда: Астрахань


Вернуться в Общее

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 8

Рейтинг@Mail.ru