powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / RealThinClient синхронный запрос
10 сообщений из 10, страница 1 из 1
RealThinClient синхронный запрос
    #39450007
mity
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Здравствуйте, имеется компонент на дельфи RealThinClient не могу решить проблему с синхронность.

Вот код на получение текста по ssl запросу но в ответ получаю пустоту

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
var
  rtcHttp_    :TRtcHttpClient;
  trcDate_    :TRtcDataRequest;
begin
try
  trcDate_:=TRtcDataRequest.Create(nil);
  rtcHttp_:=TRtcHttpClient.Create(nil);
  trcDate_.Client:=rtcHttp_;

  rtcHttp_.AutoConnect:=True;
  rtcHttp_.ServerAddr:='www.maps.googleapis.com';
  rtcHttp_.ServerPort:='443';
  rtcHttp_.UseSSL:=True;

  trcDate_.Request.ContentType:='application/x-www-form-urlencoded';

  trcDate_.Request.Method:='GET'; 
  trcDate_.Request.FileName:='/maps/api/place/nearbysearch/json?location=56.1322200,47.2519400&radius=50000&types=establishment&language=ru&key=AIzaSyDl-m1EgwQClXhKHbfzA5decy-JS48B_6c';          trcDate_.Request.Host:='maps.googleapis.com:443';

  trcDate_.Post(); // Post the request to the request queue
  rtcHttp_.Write;

  trcDate_.WaitForCompletion(true);

  Result:=rtcHttp_.Read;



но если я делаю для получения результата по возникшему событию, когда пришел результат ответа по запросу(асинхронный) на процедуру то все ок.

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
var
  rtcHttp_    :TRtcHttpClient;
  trcDate_    :TRtcDataRequest;
begin
try
  trcDate_:=TRtcDataRequest.Create(nil);
  rtcHttp_:=TRtcHttpClient.Create(nil);
  trcDate_.Client:=rtcHttp_;

  trcDate_.OnBeginRequest:=RtcDataReq_BeginRequest;
  trcDate_.OnDataReceived:=RtcDataReq_DataReceived;

  rtcHttp_.AutoConnect:=True;
  rtcHttp_.ServerAddr:='www.maps.googleapis.com';
  rtcHttp_.ServerPort:='443';
  rtcHttp_.UseSSL:=True;

  trcDate_.Request.ContentType:='application/x-www-form-urlencoded';

  trcDate_.Request.Method:='GET'; // Use the "HTTP POST" method
  trcDate_.Request.FileName:='/maps/api/place/nearbysearch/json?location=56.1322200,47.2519400&radius=50000&types=establishment&language=ru&key=AIzaSyDl-m1EgwQClXhKHbfzA5decy-JS48B_6c'; 
  trcDate_.Request.Host:='maps.googleapis.com:443'; // Set the "Host" HTTP header

  trcDate_.Post(); 



procedure TForm1.RtcDataReq_BeginRequest(Sender: TRtcConnection);
var
 Cli:TRtcDataClient absolute Sender;
begin
Cli.Write;
end;

procedure TForm1.RtcDataReq_DataReceived(Sender: TRtcConnection);
var
    Cli:TRtcDataClient absolute Sender;
begin
  // We want to wait for the whole response ...
    if Cli.Response.Done then
    begin
     Memo1.Lines.Text:=Cli.Read;
    end;
end;



по дебагу видно что событие RtcDataReq_DataReceived на получение результата приходит несколько раз и на 3-4 раз я поучаю необходимые данные. Но мне нужно в получить результат в синхронном режиме в одном потоке, попробывал добавить такой вот код в конце процедуры запроса
Код: pascal
1.
2.
3.
4.
5.
  while not rtcHttp_.Response.Done  do
  begin
  rtcHttp_.Flush;
  rtcHttp_.LeaveEvent;
  end;


но получаю пустой запрос, помогите кто знает как решить данную проблему.
...
Рейтинг: 0 / 0
RealThinClient синхронный запрос
    #39450033
Фотография Кроик Семён
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
сам не делал, но вот линк нагуглился: http://www.realthinclient.com/sdkarchive/index391a.html?cmd=viewtopic&topic_id=53&section_id=9&sid=]RealThinClient Forums --> RTC SDK SUPPORT --> WaitForCompletion
...
Рейтинг: 0 / 0
RealThinClient синхронный запрос
    #39450035
Фотография Кроик Семён
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
P.S.
а вообще, если о синхронных запросах идет речь, то можно было бы synapse использовать, там синхронность есть цель создания этой библиотеки
...
Рейтинг: 0 / 0
RealThinClient синхронный запрос
    #39450053
mity
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ни чего из той статьи не помогло.
А synapse не использую из за долгого времени обработки запроса по сравнению с RTC.
...
Рейтинг: 0 / 0
RealThinClient синхронный запрос
    #39450134
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mity,

1. может быть имеет смысл разобраться, что не так с обработкой?
2. асинхронный режим совсем не подходит?
...
Рейтинг: 0 / 0
RealThinClient синхронный запрос
    #39450146
vkorshun
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
На сколько я понимаю, обработку получения данных надо делать в TRtcDataRequest.OnDataReceived. Собирать их, например, в строку. А WaitForCompletion(true) сработает когда все данные будут получены. Также надо обрабатывать ошибки . На Reject и Abort - отдельные события.
...
Рейтинг: 0 / 0
RealThinClient синхронный запрос
    #39450155
mity
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
vkorshun,
На данный момент я так и делаю, но хотелось бы не ждать пока запрос обработается, но хотелось бы решить проблему нормальным способом т.е в одной процедуре.
Может быть пакет приходит несколькими частями, и в компоненте я не могу прочитать все части, а вижу только первую пришедшую часть ответа. Ведь другие запросы я нормально обрабатываю, например GET http
...
Рейтинг: 0 / 0
RealThinClient синхронный запрос
    #39450169
vkorshun
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
1. Не понятно зачем. Библиотека заточена на ассинхронный режим работы.
2. Можно написать свой компонент унаследовавшись от текущего. Внутри определить переменную в которую будет писаться ответ. В начале запроса сбрасывть ее. Переопределить метеод получения данных. Обращаться к этой переменной после WaitForCompletion. Но, что будет если запрос будет выполнятся долго?
...
Рейтинг: 0 / 0
RealThinClient синхронный запрос
    #39450738
RTC
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
RTC
Гость
mity, приветствую.

Когда-то на RTC 6.3Х для подобных задач делал хелпер (код, правда, для FPC, работает из служб / dll).
Надеюсь, чем-то поможет.


Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
unit ExtRtcHttpReq;

{$mode objfpc}{$H+}

interface

uses
  // RTC
  rtcInfo, rtcHttpCli, rtcDataCli, rtcConn,
  //
  Classes, SysUtils;

type

  { TRtcRequestWrapper }

  TRtcRequestWrapper = class
  private
    FRequest: TRtcDataRequest;
    FClient: TRtcHttpClient;
    FContent: string;
    FResponse: string;
    FConnectionError: string;
    FStatusCode: Integer;
    FStatusText: string;
    procedure BeginRequest(Sender: TRtcConnection);
    procedure ConnectError(Sender: TRtcConnection; E: Exception);
    procedure ConnectFail(Sender: TRtcConnection);
    procedure DataReceived(Sender: TRtcConnection);
  public
    constructor Create(const Method, Url, FileName, ContentType, Content: string; const UserName: string = ''; const UserPassword: string = '');
    destructor Destroy; override;
    procedure Execute;
    //property Client: TRtcHttpClient read FClient;
    //property Request: TRtcDataRequest read FRequest;
    property ResponseText: string read FResponse;
    property StatusCode: Integer read FStatusCode;
    property StatusText: string read FStatusText;
  end;

function HttpRequest(const Method, Url, FileName, ContentType, Content: string; out ContentOut: string; const UserName: string = ''; const UserPassword: string = ''): Integer;

var
  // Ожидание ответа после установки соединения
  RequestAfterConnectTimeout: Integer = 10;

resourcestring
  STimeoutExpired = 'Connection problems, response timed out';

implementation

uses
  StrUtils;

{ HttpRequest }

function HttpRequest(const Method, Url, FileName, ContentType, Content: string; out ContentOut: string; const UserName, UserPassword: string): Integer;
begin
  with TRtcRequestWrapper.Create(Method, Url, FileName, ContentType, Content, UserName, UserPassword) do
  try
    Execute;
    ContentOut := ResponseText;
    Result := StatusCode;
  finally
    Free;
  end;
end;

{ ExtractUrlParams }

procedure ExtractUrlParams(const Url: string; out UseSSL: Boolean; out ServerAddr, ServerPort: string);
var
  I: SizeInt;
begin
  ServerAddr := Url;
  UseSSL := AnsiStartsText('https://', ServerAddr);
  if UseSSL then
    Delete(ServerAddr, 1, Length('https://'))
  else if AnsiStartsText('http://', ServerAddr) then
    Delete(ServerAddr, 1, Length('http://'));
  I := Pos(':', ServerAddr);
  if I > 0 then
  begin
    ServerPort := Copy(ServerAddr, I + 1, Length(ServerAddr) - 2);
    SetLength(ServerAddr, I - 1);
  end else
    ServerPort := BoolToStr(UseSSL, '443', '80');
end;

{ TRtcRequestWrapper }

procedure TRtcRequestWrapper.BeginRequest(Sender: TRtcConnection);
begin
  with TRtcDataClient(Sender) do
    Write(FContent);
end;

procedure TRtcRequestWrapper.ConnectError(Sender: TRtcConnection; E: Exception);
begin
  FConnectionError := Format('Connection Error (%s): %s', [E.ClassName, E.Message]);
end;

procedure TRtcRequestWrapper.ConnectFail(Sender: TRtcConnection);
begin
  FConnectionError := 'Connection Fail';
end;

procedure TRtcRequestWrapper.DataReceived(Sender: TRtcConnection);
begin
  with TRtcDataClient(Sender) do
    if Response.Done then
    begin
      FResponse := FResponse + Read;
      FStatusCode := Response.StatusCode;
      FStatusText := Response.StatusText;
    end;
end;

constructor TRtcRequestWrapper.Create(const Method, Url, FileName, ContentType, Content, UserName, UserPassword: string);
var
  UseSSL: Boolean;
  ServerAddr, ServerPort: string;
begin
  ExtractUrlParams(Url, UseSSL, ServerAddr, ServerPort);

  FClient := TRtcHttpClient.Create(nil);
  FClient.OnConnectError := @ConnectError;
  FClient.OnConnectFail := @ConnectFail;
  FClient.ServerAddr := ServerAddr;
  FClient.ServerPort := ServerPort;
  FClient.UseSSL := UseSSL;
  FClient.AutoConnect := True;
  FClient.ReconnectOn.ConnectLost := True;
  FClient.Blocking := True;
  FClient.UserLogin.UserName := UserName;
  FClient.UserLogin.UserPassword := UserPassword;
  //
  //FClient.MultiThreaded := True;
  FClient.Timeout.AfterConnect := RequestAfterConnectTimeout;

  FRequest := TRtcDataRequest.Create(nil);
  FRequest.OnBeginRequest := @BeginRequest;
  FRequest.OnDataReceived := @DataReceived;
  FRequest.Client := FClient;
  FRequest.Request.Method := Method;
  FRequest.Request.Host := ServerAddr;
  FRequest.Request.FileName := FileName;
  FRequest.Request.ContentType := ContentType;

  FContent := Content;
end;

destructor TRtcRequestWrapper.Destroy;
begin
  FRequest.Free;
  FClient.Free;
  inherited Destroy;
end;

procedure TRtcRequestWrapper.Execute;
begin
  FRequest.Post;
  if FClient.TimedOut then
    raise Exception.Create(STimeoutExpired);
  if FConnectionError > '' then
    raise Exception.Create(FConnectionError);
end;

end.




Вызывать примерно так:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
try
  Status := HttpRequest(
    'POST', 
    'https://www.maps.googleapis.com', 
    '/maps/api/place/nearbysearch/json?location=56.1322200,47.2519400&radius=50000&types=establishment&language=ru&key=AIzaSyDl-m1EgwQClXhKHbfzA5decy-JS48B_6c', 
    'application/x-www-form-urlencoded', 
    '', // возможно, нужно добавить контроль пустой строки в TRtcRequestWrapper.BeginRequest
    ContentOut);
except
  // 
end;
...
Рейтинг: 0 / 0
RealThinClient синхронный запрос
    #39595143
kolio
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
не забудьте добавить еще 2 обработчика:
FRequest.OnResponseAbort := ResponseAbort;
FRequest.OnResponseReject := ResponseReject;
...
Рейтинг: 0 / 0
10 сообщений из 10, страница 1 из 1
Форумы / Delphi [игнор отключен] [закрыт для гостей] / RealThinClient синхронный запрос
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]