Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 2007.06.24;
Скачать: [xml.tar.bz2];

Вниз

Переход с Indy 9.0 на Indy 10.0 (вопрос для знатоков Indy)   Найти похожие ветки 

 
Сатир   (2007-05-23 11:45) [0]

В связи с глючностью девятой версии при работе с сокетами, а именно, теряет ID потока, который веделен для следующего соединения, возникла необходимость перейти на десятую версию.
Но вот незадача: все необходимые обработчики сервера OnExecute, OnConnect, OnDisconnect теперь принимают входной параметр AContext:TIdContext, в отличии от пердыдущей версии, где они принимали  AThread: TIdPeerThread. Соответственно многие участки реализации этих методов были завязаны на AThread, а теперь имеем AContext.
А теперь внимание - вопрос(понимаю, он будет непростой, но всё же  осмелюсь его задать):
Каг связать AThread и AContext?


 
umbra ©   (2007-05-23 11:54) [1]


> Каг связать AThread и AContext?
>

что имеется в виду? У обоих есть св-во Connection. Управление собственно потоком в AContext происходит через св-во Yarn


 
Сатир   (2007-05-23 12:25) [2]


> что имеется в виду?

вот пример кода, основанного на старой версии:
procedure TRecDM.IdTCPServerConnect(AThread: TIdPeerThread});
var
 NewClient: PClient;
begin
 try
   
   GetMem(NewClient, SizeOf(TClient));

   NewClient.DNS := AThread.Connection.LocalName;
   NewClient.Connected := Now;
   NewClient.LastAction := NewClient.Connected;
   NewClient.Thread := AThread;
   
   AThread.Data := TObject(NewClient);

   try
     Clients.LockList.Add(NewClient);
   finally
     Clients.UnlockList;
   end;
   SetConnectionStatus(2, 1);
 except
 end;
end;

Как тут заменить AThread на AContext?
тоесть AThread=AContext.Yarn?


 
umbra ©   (2007-05-23 12:47) [3]

procedure TRecDM.IdTCPServerConnect(AContext: TIdContext);
var
NewClient: PClient;
begin
try
 
  GetMem(NewClient, SizeOf(TClient));

  //NewClient.DNS := AThread.Connection.LocalName;
  //у Connection больше нет св-ва LocalName
  NewClient.Connected := Now;
  NewClient.LastAction := NewClient.Connected;
  NewClient.Thread := AContext.Yarn;
  //если нужен именно поток, создаваемый для клиентской сессии
 
  AContext.Data := TObject(NewClient);

  try
    Clients.LockList.Add(NewClient);
  finally
    Clients.UnlockList;
  end;
  SetConnectionStatus(2, 1);
except
end;
end;


правда, не совсем понятно, зачем это надо. У ТIdTCPServer есть св-во Contexts, в котором содержатся все наличные контексты сессий.


 
umbra ©   (2007-05-23 13:02) [4]

вообще, в инди 10 сильно изменилась архитектура. По-моему, в лучшую строну. За инициализацию и прерывание соединения теперь отвестсвенно TIdTCPConnection, за ввод-вывод на установленном соединении - TIDIOHandler, за доп. обработку сетевого траффика (сжатие или там шифрование) - TIDIntercept.


 
Сатир   (2007-05-23 13:04) [5]

ещё один небольшой вопрос по новому Инди
Тут почитал мануал по новой версии, там что-то предложили для управления потоками сервера использоваться Scheduler

Scheduler is a TIdScheduler property that provides the mechanism used for thread or fiber management for client connections to the server. The Scheduler handles creation, execution, and termination of tasks for client connections found in Contexts.

Copyright © 1993-2006, Chad Z. Hower (aka Kudzu) and the Indy Pit Crew. All rights reserved.

Эта штука мне может как-нить пригодиться в данном случае?
И есть ли где-нить описаны отличия и нововведения в десятой версии?
Надо бы ещё мануал полистать...


 
umbra ©   (2007-05-23 13:08) [6]


>Scheduler is a TIdScheduler property that provides the mechanism used for thread >or fiber management for client connections to the server.
> Эта штука мне может как-нить пригодиться в данном случае?

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


 
Сатир   (2007-05-23 13:12) [7]


> правда, не совсем понятно, зачем это надо

мне тоже пока вся архитектура не совсем ясна, дали пару дней исправить ошибку, чтоб работало.
Так что особо много времени вникать нету, приходится прикручивать к тому, что есть.
Хотя на досуге с удовольствием переписал бы некоторые куски...


 
IMHO ©   (2007-05-23 13:27) [8]

Кто юзает Индайку 10, скажите: пофиксили ли они TidMessage? Бо в девятке он был больно глючный, пришлось свой писать.


 
umbra ©   (2007-05-23 13:30) [9]


> офиксили ли они TidMessage? Бо в девятке он был больно глючный

и что за глюки были?


 
IMHO ©   (2007-05-23 13:41) [10]

А ты не встречался с ними, что ли?


 
umbra ©   (2007-05-23 13:46) [11]

9-кой не пользовался. в 10-ке не встречался, но в "сетях" обсуждался по крайней мере один - неправильное указание часового пояса в заголовке Date.


 
IMHO ©   (2007-05-23 14:01) [12]

На некоторых сообщениях безбожно зависал (где-то шло зацикливание, видимо).

На некоторых корректных сообщениях давал ошибку:
Uneven size in DecodeToStream (эти EML-файлы прекрасно открывались в MS Outlook Express)

Про некоторые кодировки девятая версия вообще не знала.

Не все ContentTransferEncoding поддерживались.

Это только то, что вспомнилось сразу.


 
Сатир   (2007-05-23 15:13) [13]


> Кто юзает Индайку 10, скажите: пофиксили ли они TidMessage?

да, пофиксили.
у меня на прошлой работе с ним были проблеммы. Установил десятую версию и всё полечилось.

Я так посмотрел, девятая версия вообще 2002 года выпуска, за пять лет можно было довести до ума. И вроде таки довели. По многим недочётам.


 
IMHO ©   (2007-05-23 15:40) [14]


> Сатир   (23.05.07 15:13) [13]


Дай, плиз, ссылку скачать Indy 10 for Delphi 5.


 
Сатир   (2007-05-23 15:48) [15]

http://www.indyproject.com


 
Сатир   (2007-05-23 17:17) [16]

а как адаптировать такую строчку?

AThread.Synchronize(ShowServerConnect);


 
umbra ©   (2007-05-23 17:32) [17]

AContext.Yarn.Synchronize(ShowServerConnect);


 
Сатир   (2007-05-23 17:51) [18]


> AContext.Yarn.Synchronize(ShowServerConnect);

а это будет работать?

нашел описание класса TIdYarn
unit IdYarn;

interface

type
 TIdYarn = class(TObject)
 protected
 public
 end;

implementation

{ TIdYarn }

end.

и что-то незаметил там реализацию этого метода...
может у меня исходники не той версии?


 
umbra ©   (2007-05-23 18:01) [19]


> нашел описание класса TIdYarn

этот класс - просто заместитель для дизайн-тайма. В это время неизвестно, как будет реализована многопоточность на сервере - на основе собс-но потоков (TIdThread) или на основе волокон (TIdFiber). Соответственно, в рантайм св-во Yarn будет одного из этих двух типов. Если при создании класса явно ничего не указано, по умолчанию используются потоки (TIdThread). В инди 9 были только потоки.


 
Сатир   (2007-05-23 18:06) [20]

спасибо, очень познавательно.

А вот ещё кусочек, который меня смутил:

function TRecDM.SendAnswerMSG(StringList: TStringList): TBackMsg;
var
 RecClient: PClient;
 RecThread: TIdPeerThread;
 i: integer;
begin
 try
   with Clients.LockList do
   begin
     for i := 0 to Count - 1 do // iterate through client-list
     begin
       RecClient := Items[i]; // get client-object
       RecThread := RecClient.Thread; // get client-thread out of it
       RecThread.Connection.OpenWriteBuffer();
       RecThread.Connection.WriteStrings(StringList);
       RecThread.Connection.FlushWriteBuffer();
       RecThread.Connection.CloseWriteBuffer;

Где взять эти 4 метода?
пробовал заменить TIdPeerThread на TIdContext - ничего не вышло:(


 
umbra ©   (2007-05-23 18:29) [21]

Connection.IOHandler - там все методы чтения-записи


 
Сатир   (2007-05-23 18:59) [22]

пасибо, разобрался, но на всякий случай проконтролируй, плиз, всё ли верно:
старый вариант
  {   RecThread := RecClient.Thread; // get client-thread out of it
       RecThread.Connection.OpenWriteBuffer();
       RecThread.Connection.WriteStrings(StringList);
       RecThread.Connection.FlushWriteBuffer();
       RecThread.Connection.CloseWriteBuffer;
     }

новый вариант
       RecThread.Connection.IOHandler.WriteBufferOpen;
       RecThread.Connection.IOHandler.Write(StringList);
       RecThread.Connection.IOHandler.WriteBufferFlush;
       RecThread.Connection.IOHandler.WriteBufferClose;

и последний вопрос
откуда взять LocalName?


 
IMHO ©   (2007-05-23 20:00) [23]


> Сатир   (23.05.07 15:48) [15]
>
> http://www.indyproject.com


Ты сам хоть ходил по ссылке, что приводишь тут?


 
Сатир   (2007-05-24 10:57) [24]


> Ты сам хоть ходил по ссылке, что приводишь тут?


не, не ходил. так, по памяти написал


 
umbra ©   (2007-05-24 11:09) [25]


> http://www.indyproject.com

http://indyproject.org/Sockets/Download/index.EN.aspx


> откуда взять LocalName?
>

если речь идет о имени компьютера, где работает сервер, то, например GetComputerName должно помочь


 
Сатир   (2007-05-24 11:25) [26]


> umbra ©

Премного благодарен.


 
Сатир   (2007-05-24 17:55) [27]


> umbra ©   (23.05.07 17:32) [17]
> AContext.Yarn.Synchronize(ShowServerConnect);


вот это не работает. говорит: Undeclared identifier "Synchronize"

как быть?


 
umbra ©   (2007-05-24 19:04) [28]


> как быть?
>


привести к нужному типу:

TidThread(AContext.Yarn).Synchronize(ShowServerConnect);


 
Сатир   (2007-05-25 10:40) [29]


> привести к нужному типу:
>
> TidThread(AContext.Yarn).Synchronize(ShowServerConnect);
>

да, вчера сам уже догадался, потому как вспомнил, что

> этот класс - просто заместитель для дизайн-тайма.

наконец смог скомпилить проект. теперь самое интересное - это его тестирование.

Если интересно, то это сервис шлюза, который получает данные от SOLVO и ложит их в Oracle.


 
Сатир   (2007-05-25 12:01) [30]

такой вопрос:

function TRecDM.SendAnswerMSG(StringList: TStringList): TBackMsg;
var
 RecClient: PClient;
 RecThread:TIdContext;
 i: integer;
begin
 try
   with Clients.LockList do
   begin
     for i := 0 to Count - 1 do // iterate through client-list
     begin

       RecClient := Items[i]; // get client-object
       RecThread:=TIdContext.Create(Connection,RecClient.Thread);<-где взять Connection? у idTCPServer такого свойства нету
     //  RecThread.Yarn:=RecClient.Thread; <-свойство Readonly
       RecThread.Connection.IOHandler.WriteBufferOpen;
       RecThread.Connection.IOHandler.Write(StringList);
       RecThread.Connection.IOHandler.WriteBufferFlush;
       RecThread.Connection.IOHandler.WriteBufferClose;
     
Нужно ли создавать экземпляр TIdContext в цикле и освобождать в цикле или можно один раз создать перед циклом и нужно ли вообще освобождать этот экземпляр?


 
umbra ©   (2007-05-25 12:24) [31]

а что здесь вообще происходит? судя по всему кто-то шлет кому-то ответ на что-то. а конкретней можно? зачем сервер создает соединения?

кроме того у TIdContext.Create 3 параметра, один из них как раз Yarn.


 
Сатир   (2007-05-25 12:31) [32]

добавил в структуру
PClient = ^TClient;
 TClient = Record // Object holding data of client (see events)
   DNS: String[20]; { Hostname }
   Connected, { Time of connect }
   LastAction: TDateTime; { Time of last transaction }
   Thread: Pointer; { Pointer to thread }
   Connection: TidTCPConnection;
 End;
поле Connection и заполняю его
в методе
Procedure TRecDM.IdTCPServerConnect(AContext: TIdContext {AThread: TIdPeerThread});
Var
 NewClient: PClient;
Begin
 Try
       GetMem(NewClient, SizeOf(TClient));

   //    NewClient.DNS := {AThread}AContext.Connection.LocalName;
   NewClient.DNS := GetCompName;
   NewClient.Connected := Now;
   NewClient.LastAction := NewClient.Connected;
   NewClient.Thread := {AThread} AContext.Yarn;
   {AThread}AContext.Data := TObject(NewClient);
   NewClient.Connection := AContext.Connection;
   Try
     Clients.LockList.Add(NewClient);
   Finally
     Clients.UnlockList;
   End;
   SetConnectionStatus(2, 1);

так вроде выкрутился


 
Сатир   (2007-05-25 12:32) [33]


> зачем сервер создает соединения?

ну это ж шлюз, который общается с SOLVO, вот они и общаются друг с другом...


 
Сатир   (2007-05-25 18:13) [34]

а всё таки не хочет работать этот кусок:
Function TRecDM.SendAnswerMSG(StringList: TStringList): TBackMsg;
Var
 RecClient: PClient;
 RecThread: TIdContext;
 i: integer;
Begin
 Try
   With Clients.LockList Do
   Begin
     For i := 0 To Count - 1 Do // iterate through client-list
     Begin

       RecClient := Items[i]; // get client-object
       RecThread := TIdContext.Create(RecClient.Connection, RecClient.Thread);
       //  RecThread.Yarn:=RecClient.Thread;
       Try
         RecThread.Connection.IOHandler.WriteBufferOpen;
         RecThread.Connection.IOHandler.Write(StringList);
         RecThread.Connection.IOHandler.WriteBufferFlush;
         RecThread.Connection.IOHandler.WriteBufferClose;

вываливается на WriteBufferOpen с ошибкой
---------------------------
Debugger Exception Notification
---------------------------
Project WMS_Gate.exe raised exception class EAccessViolation with message "Access violation at address 006B6B5F in module "WMS_Gate.exe". Read of address 00000000". Process stopped. Use Step or Run to continue.
---------------------------
OK   Help  
---------------------------
---------------------------
Debugger Exception Notification
---------------------------
Project WMS_Gate.exe raised exception class EInvalidPointer with message "Invalid pointer operation". Process stopped. Use Step or Run to continue.
---------------------------
OK   Help  
---------------------------
какой-то поинтер не туда глядит...



Страницы: 1 вся ветка

Форум: "Прочее";
Текущий архив: 2007.06.24;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.54 MB
Время: 0.044 c
2-1180031134
DemonP
2007-05-24 22:25
2007.06.24
отлов выхода из спящего режима


2-1180954130
nali
2007-06-04 14:48
2007.06.24
Не рисуется иконка на кнопке в таскбаре


15-1179978466
AleKo
2007-05-24 07:47
2007.06.24
Лицензия на BDS2006


2-1180960375
UMU
2007-06-04 16:32
2007.06.24
Запись в ini файл


15-1180348932
Думкин
2007-05-28 14:42
2007.06.24
CodeGear Новосибирск





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский