Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > Интернет и сети
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 12.04.2015, 22:59
Vertex Vertex вне форума
Прохожий
 
Регистрация: 12.04.2015
Сообщения: 6
Версия Delphi: Delphi XE2
Репутация: 10
По умолчанию Indy10 и синхронизация VCL

Здравствуйте.

Подскажите пожалуйста, как сделать синхронизацию VCL в Indy10 на сервере(IdTCPServer)?

Принимаю и вывожу данные от клиента на сервере так:

Код:
procedure TForm1.IdTCPServer1Execute(AContext: TIdContext);
var
msg: string;
begin
  msg:= AContext.Connection.IOHandler.ReadLn(TEncoding.UTF8);
  Memo1.Lines.Add(msg);
end;
Ответить с цитированием
  #2  
Старый 13.04.2015, 03:51
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,029
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Серверные компоненты обрабатывают приходящие данные в потоке. Соответсвенно, нужно сделать свой метод, из которого обращаться к VCL (читай, главному потоку приложения) и вызывать его через Synchronize.
Ответить с цитированием
Этот пользователь сказал Спасибо lmikle за это полезное сообщение:
Vertex (13.04.2015)
  #3  
Старый 13.04.2015, 07:43
Vertex Vertex вне форума
Прохожий
 
Регистрация: 12.04.2015
Сообщения: 6
Версия Delphi: Delphi XE2
Репутация: 10
По умолчанию

Спасибо, а примерчик если не трудно приведите пожалуйста, в гугле что-то не получается найти ничего внятного по этому вопросу.
В Indy10 идёт TIdContext, в нём нету метода Synchronize.

Последний раз редактировалось Vertex, 13.04.2015 в 07:49.
Ответить с цитированием
  #4  
Старый 13.04.2015, 08:32
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,029
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Лень писать пример.
Помиотри тут примеры и идеи:
http://codeverge.com/embarcadero.del...a-form/1069509
http://codeverge.com/embarcadero.del...l-form/1062438
http://embarcadero.newsgroups.archiv...103155640.html
Ответить с цитированием
  #5  
Старый 13.04.2015, 13:24
Vertex Vertex вне форума
Прохожий
 
Регистрация: 12.04.2015
Сообщения: 6
Версия Delphi: Delphi XE2
Репутация: 10
По умолчанию

Посмотрел, нормальных примеров не нашел. Понял что надо использовать TIdSync или TIdNotify, вроде как TIdNotify получше.
Если кто-нибудь приведёт пример, буду очень признателен.

Вопрос остаётся пока не решенным.

Последний раз редактировалось Vertex, 13.04.2015 в 13:48.
Ответить с цитированием
  #6  
Старый 13.04.2015, 16:35
Vertex Vertex вне форума
Прохожий
 
Регистрация: 12.04.2015
Сообщения: 6
Версия Delphi: Delphi XE2
Репутация: 10
По умолчанию

Вот есть такой код:

Клиент:
Код:
unit Unit1;
 
interface
 
uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, IdBaseComponent, ShellApi,
  IdComponent, IdTCPConnection, IdTCPClient, Vcl.ExtCtrls, IdAntiFreezeBase,
  Vcl.IdAntiFreeze;
 
type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Edit1: TEdit;
    Button1: TButton;
    IdTCPClient1: TIdTCPClient;
    Timer1: TTimer;
    IdAntiFreeze1: TIdAntiFreeze;
    Edit2: TEdit;
    Button2: TButton;
    Button3: TButton;
    procedure Timer1Timer(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure Button2Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.dfm}
 
procedure TForm1.Button2Click(Sender: TObject); // Для запуска множества клиентов, указанных в Edit2
var
i: integer;
begin
for i:=0 to StrToInt(Edit2.Text) - 1 do
begin
ShellExecute(Handle, 'open', PChar(Application.ExeName), nil, nil, SW_SHOW);
application.ProcessMessages;
sleep(333);
end;
end;
 
 
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
IdTCPClient1.Disconnect;
end;
 
 
procedure TForm1.FormCreate(Sender: TObject); // Сразу подключаем клиентов, для тестирования большого кол-ва
begin
  IdTCPClient1.Port := 8080;
  IdTCPClient1.Host := '127.0.0.1';
  IdTCPClient1.Connect;
end;
 
 
procedure TForm1.Timer1Timer(Sender: TObject);
begin
// Отправка сообщения по таймеру для теста
if IdTCPClient1.Connected then
IdTCPClient1.IOHandler.WriteLn('Тестирование сервера', TEncoding.UTF8);
 
end;
 
end.

Сервер_1 - (через TIdSync) :
Код:
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, IdContext, IdCustomTCPServer, IdTCPServer, IdBaseComponent,
  IdComponent, IdTCPConnection, IdTCPClient, Vcl.ExtCtrls, IdSync ;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    IdTCPServer1: TIdTCPServer;
    procedure FormCreate(Sender: TObject);
    procedure IdTCPServer1Execute(AContext: TIdContext);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

type
   TMySync = class(TIdSync)
   protected
     FMessage: string;
     procedure DoSynchronize; override;
   public
     class procedure AddLine(const S: String);
   end;

  var
  Form1: TForm1;

implementation

{$R *.dfm}
var
msg: string;

procedure TMySync.DoSynchronize;
 begin
   Form1.Memo1.Lines.Add(FMessage);
   if Form1.Memo1.Lines.Count > 50 then Form1.Memo1.Clear;
 end;

class procedure TMySync.AddLine(const S: String);
 var
   MySync: TMySync;
 begin
   MySync := TMySync.Create;
   try
     MySync.FMessage := S;
     MySync.Synchronize;
   finally
     MySync.Free;
   end;
 end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  IdTCPServer1.DefaultPort := 8080;
  IdTCPServer1.Active := true;
end;

procedure TForm1.IdTCPServer1Execute(AContext: TIdContext);
var
MySync: TMySync;
begin
  msg:= AContext.Connection.IOHandler.ReadLn(TEncoding.UTF8);
  TMySync.AddLine(msg);
end;

end.

Сервер_2 - (через TidNotify) :
Код:
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, IdContext, IdCustomTCPServer, IdTCPServer, IdBaseComponent,
  IdComponent, IdTCPConnection, IdTCPClient, Vcl.ExtCtrls, IdSync,
  IdAntiFreezeBase, Vcl.IdAntiFreeze;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    IdTCPServer1: TIdTCPServer;
    IdAntiFreeze1: TIdAntiFreeze;
    procedure FormCreate(Sender: TObject);
    procedure IdTCPServer1Execute(AContext: TIdContext);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

type
  TMyNotify = class(TidNotify)
  private
    FMyData: string;
  protected
    procedure DoNotify; override;
  end;

  var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TMyNotify.DoNotify;
begin
 Form1.Memo1.Lines.Add(FMyData);
 if Form1.Memo1.Lines.Count > 50 then Form1.Memo1.Clear;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  IdTCPServer1.DefaultPort := 8080;
  IdTCPServer1.Active := true;
end;

procedure TForm1.IdTCPServer1Execute(AContext: TIdContext);
var
MyNotify: TMyNotify;
begin
  MyNotify := TMyNotify.Create;
  MyNotify.FMyData:= AContext.Connection.IOHandler.ReadLn(TEncoding.UTF8); 
  MyNotify.Notify;
end;

end.

С клиентов к серверу идут каждые 100мс сообщения. Что первый вариант сервера, что второй их принимает и выводит в Мемо1.
Но если подключить 200 клиентов, то сервер в обоих вариантах - зависает. Так же идёт утечка памяти в обоих вариантах серверов.

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

Последний раз редактировалось Vertex, 13.04.2015 в 16:48.
Ответить с цитированием
  #7  
Старый 15.04.2015, 08:35
Vertex Vertex вне форума
Прохожий
 
Регистрация: 12.04.2015
Сообщения: 6
Версия Delphi: Delphi XE2
Репутация: 10
По умолчанию

Уважаемы профессионалы!

Вы бы хоть сказали, правильно ли сделана синхронизация на сервере_1 и на сервере_2 ?

А то все пробежались мимо, и на этом нерешенный вопрос повис в воздухе.
Ответить с цитированием
  #8  
Старый 18.04.2015, 23:11
Vertex Vertex вне форума
Прохожий
 
Регистрация: 12.04.2015
Сообщения: 6
Версия Delphi: Delphi XE2
Репутация: 10
По умолчанию

Все тормоза и зависание, а отсюда и рост памяти были из-за грёбаного грузного компонента Мемо, ни один стандартный компонент не подошел для вывода разноцветных строк, даже при рисовании на канве зависал сервер при 500 клиентах.
Выручило динамическое создание множества Label и из них сделал лист,
даже на 700 клиентах ничего не зависает и память не растёт.
Сервер через TIdSync.

Последний раз редактировалось Vertex, 18.04.2015 в 23:18.
Ответить с цитированием
  #9  
Старый 19.09.2015, 19:17
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,029
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Не, нет у тебя там ничего, что тормозило бы. Либо ты не весь код показал. Проблема может быть только одна - отрисовка. Все-таки Memo - оконный компонент. И разные потоки могли тормозиться из-за синхронизации отрисовки.
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 07:44.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter