Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Delphi [игнор отключен] [закрыт для гостей] / RealThinClient синхронный запрос / 10 сообщений из 10, страница 1 из 1
08.05.2017, 01:34
    #39450007
mity
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
RealThinClient синхронный запрос
Здравствуйте, имеется компонент на дельфи 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
08.05.2017, 11:11
    #39450033
Кроик Семён
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
RealThinClient синхронный запрос
сам не делал, но вот линк нагуглился: http://www.realthinclient.com/sdkarchive/index391a.html?cmd=viewtopic&topic_id=53&section_id=9&sid=]RealThinClient Forums --> RTC SDK SUPPORT --> WaitForCompletion
...
Рейтинг: 0 / 0
08.05.2017, 11:14
    #39450035
Кроик Семён
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
RealThinClient синхронный запрос
P.S.
а вообще, если о синхронных запросах идет речь, то можно было бы synapse использовать, там синхронность есть цель создания этой библиотеки
...
Рейтинг: 0 / 0
08.05.2017, 12:40
    #39450053
mity
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
RealThinClient синхронный запрос
Ни чего из той статьи не помогло.
А synapse не использую из за долгого времени обработки запроса по сравнению с RTC.
...
Рейтинг: 0 / 0
08.05.2017, 17:33
    #39450134
makhaon
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
RealThinClient синхронный запрос
mity,

1. может быть имеет смысл разобраться, что не так с обработкой?
2. асинхронный режим совсем не подходит?
...
Рейтинг: 0 / 0
08.05.2017, 18:25
    #39450146
vkorshun
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
RealThinClient синхронный запрос
На сколько я понимаю, обработку получения данных надо делать в TRtcDataRequest.OnDataReceived. Собирать их, например, в строку. А WaitForCompletion(true) сработает когда все данные будут получены. Также надо обрабатывать ошибки . На Reject и Abort - отдельные события.
...
Рейтинг: 0 / 0
08.05.2017, 18:51
    #39450155
mity
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
RealThinClient синхронный запрос
vkorshun,
На данный момент я так и делаю, но хотелось бы не ждать пока запрос обработается, но хотелось бы решить проблему нормальным способом т.е в одной процедуре.
Может быть пакет приходит несколькими частями, и в компоненте я не могу прочитать все части, а вижу только первую пришедшую часть ответа. Ведь другие запросы я нормально обрабатываю, например GET http
...
Рейтинг: 0 / 0
08.05.2017, 19:39
    #39450169
vkorshun
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
RealThinClient синхронный запрос
1. Не понятно зачем. Библиотека заточена на ассинхронный режим работы.
2. Можно написать свой компонент унаследовавшись от текущего. Внутри определить переменную в которую будет писаться ответ. В начале запроса сбрасывть ее. Переопределить метеод получения данных. Обращаться к этой переменной после WaitForCompletion. Но, что будет если запрос будет выполнятся долго?
...
Рейтинг: 0 / 0
10.05.2017, 13:12
    #39450738
RTC
RTC
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
RealThinClient синхронный запрос
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
01.02.2018, 18:12
    #39595143
kolio
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
RealThinClient синхронный запрос
не забудьте добавить еще 2 обработчика:
FRequest.OnResponseAbort := ResponseAbort;
FRequest.OnResponseReject := ResponseReject;
...
Рейтинг: 0 / 0
Форумы / Delphi [игнор отключен] [закрыт для гостей] / RealThinClient синхронный запрос / 10 сообщений из 10, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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