Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.05.06;
Скачать: CL | DM;

Вниз

OnConnect в TidTCPServer и обращение к базе.   Найти похожие ветки 

 
DVM ©   (2006-11-03 13:26) [0]

Возник вот какой вопрос:

Есть сервер TidTCPServer, принимающий соединения от клиентов. При подключении клиента мне надо в базу MSAccess занести запись о IP адресе и порте клиента и сразу отключить оного. Зачем так надо - неважно. Общение с базой через ADO.

Вопрос в следующем: должен ли я оборачивать в критические секции вызов функции добавления записи в лог в OnConnect сервера? Без критических секций виснет сервер.

т.е. так правильно:


procedure TfrmMain.IdTCPServerConnect(AThread: TIdPeerThread);
var
 Zone: integer;
 Sensor: integer;
 State: boolean;
begin
 try
   cs.Enter;
   try
     Log(AThread.Connection.Socket.Binding.PeerIP, ....);
   finally
     cs.Leave;
   end;
 finally
   AThread.Connection.Disconnect;
 end;
end;


 
Сергей М. ©   (2006-11-03 13:39) [1]


> должен ли


А это не важно. Хоть с КС хоть без нее - логика не верна концептуально.

Каждый доп.трэд должен создавать собственную ADO-коннекцию, ты же пытаешься использовать одну-единственную коннекцию для всех своих тредов.


 
Reindeer Moss Eater ©   (2006-11-03 13:42) [2]

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

Тогда cs ему поможет


 
DVM ©   (2006-11-03 13:43) [3]


> Хоть с КС хоть без нее - логика не верна концептуально.

Да, я потому и спрашиваю, чувствую что не все хорошо в данном коде.
Но с критическими секциями работает нормально ведь.
Да и есть ли смысл так усложнять если надо зафиксировать лишь факт коннекта.
Я где то читал еще что если динамически создавать ADO Connection возникает утечка памяти.


 
DVM ©   (2006-11-03 13:44) [4]


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

Мне параллельность не нужна, мне надо просто фиксировать факт запроса. Очередность тоже не важна.


 
Reindeer Moss Eater ©   (2006-11-03 13:48) [5]

Мне параллельность не нужна, мне надо просто фиксировать факт запроса. Очередность тоже не важна.

Тогда все обращения с бд обернуть входами выходами в/из кс.
Очередной подсоединившийся клиент будет курить пока не освободится секция.


 
DVM ©   (2006-11-03 13:50) [6]

Спасибо всем, так и сделаем.


 
Сергей М. ©   (2006-11-03 15:55) [7]

Есть метод TThread.Syncronize.

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

Самое оно то для задачи автора.


 
DVM ©   (2006-11-03 16:18) [8]


> Есть метод TThread.Syncronize.

А там же параметры не передать никак в функцию.


 
Сергей М. ©   (2006-11-03 16:34) [9]


> DVM ©   (03.11.06 16:18) [8]


Это из другой оперы.


 
DVM ©   (2006-11-05 10:39) [10]

Сделал через посылку сообщения с указателем на структуру о клиенте из клиентского потока сервера в основной поток. Так удобнее, чем через Synchronize.


 
Сергей М. ©   (2006-11-05 16:38) [11]


> Так удобнее, чем через Synchronize.
> <Цитата>


Вот уж глупости


 
DVM ©   (2006-11-06 15:18) [12]


> Вот уж глупости

Вот уж не глупости. А вполне логичный и надежный вариант. Synchronize в конце концов тоже шлет сообщение.

Я что-то не представляю себе как в класс TIdPeerThread добавить процедуру, которую бы потом можно было передать в качестве праметра в Synchronize; Плюс передача параметров тоже проблема.

procedure TfrmMain.IdTCPServerConnect(AThread: TIdPeerThread);
begin
 Synchronize(???);
end;

С собщением оказалось проще и короче.

Буду благодарен за разъяснения.


 
Anatoly Podgoretsky ©   (2006-11-06 15:48) [13]

> DVM  (06.11.2006 15:18:12)  [12]
Наверноprocedure TfrmMain.X;-- С уважением,Анатолий Подгорецкий  "DVM" <dvmuratov@yandex.ru> wrote in message news:1162549584.12@delphimaster.ru...  DVM © (06.11.2006 15:18) [12]  > Вот уж глупости  Вот уж не глупости. А вполне логичный и надежный вариант. Synchronize в конце концов тоже шлет сообщение.  Я что-то не представляю себе как в класс TIdPeerThread добавить процедуру, которую бы потом можно было передать в качестве праметра в Synchronize; Плюс передача параметров тоже проблема.  procedure TfrmMain.IdTCPServerConnect(AThread: TIdPeerThread);  begin   Synchronize(???);  end;  С собщением оказалось проще и короче.  Буду благодарен за разъяснения.------=_NextPart_000_0143_01C701B2.A2553C90


 
Сергей М. ©   (2006-11-06 18:23) [14]


> Synchronize в конце концов тоже шлет сообщение


В 7-ке не шлет, там это по-иному организовано.


> не представляю себе как в класс TIdPeerThread добавить процедуру,
>  которую бы потом можно было передать в качестве праметра
> в Synchronize; Плюс передача параметров тоже проблема


TPeerThread в этом плане ничем не отличаетсч от любого иного наследника TThread


 
DVM ©   (2006-11-06 22:03) [15]


> Сергей М. ©   (06.11.06 18:23) [14]

Спасибо, разбираюсь.

Вообще то с этим OnConnect от TidTCPServer в интернете и литературе сплошь и рядом странная ситуация.
OnConnect сервера однозначно выполняется в доп потоке и все пытаются прямо из другого потока обновлять логи, писать в мемо, листбох-ы и прочее. Но ведь так нельзя делать!

Например у того же М. Кэнту в книге есть строки:

procedure TFormServer. IdTCPServer1Connect (AThread: TIdPeerThread);
begin
lbLog.Items.Add. ("Connected from: " +
AThread. Connection.Socket.Binding.PeerIP);
end

Он обновляет список без всяких Synchronize.


 
Сергей М. ©   (2006-11-07 08:26) [16]


> Он обновляет список без всяких Synchronize.


Если ListBox невидим и коннект всего один, то ничего страшного не произойдет.
В противном случае жди глюков, потому что это очевидная плюха автора


 
DVM ©   (2006-11-07 10:06) [17]


> Сергей М. ©   (07.11.06 08:26) [16]

Причем пример неправильного использования подают сами разработчики Indy.

Вот из примеров Indy:


procedure TServerFrmMain.ServerConnect(AThread: TIdPeerThread);
begin
 ....
 Protocol.Lines.Add(TimeToStr(Time)+" Connection from ""+NewClient.DNS+""");
end;


Protocol это TMemo, сервер явно не для одного клиента предназначен.


 
Сергей М. ©   (2006-11-07 10:16) [18]


> DVM ©   (07.11.06 10:06) [17]


Да начхать, кто этот дурной пример подает. Важно ему не следовать в принципе.

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


 
DVM ©   (2006-11-07 10:21) [19]


> Выяснить в каком потоке вызывается обработчик того или иного
> события можно и без анализа исходников.

Ну вот я так и выяснял GetCurrentThreadID

Ну вобщем спасибо всем вопрос закрыт.



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

Текущий архив: 2007.05.06;
Скачать: CL | DM;

Наверх




Память: 0.52 MB
Время: 0.024 c
15-1176086186
Slider007
2007-04-09 06:36
2007.05.06
С днем рождения ! 7 апреля


15-1176018141
Чапаев
2007-04-08 11:42
2007.05.06
Поможыте, люди добрые!


9-1148890316
cyborg
2006-05-29 12:11
2007.05.06
Советую интерпретор


11-1158738217
BMouradov
2006-09-20 11:43
2007.05.06
KOLPrinters подвешивает программу


15-1175495841
xayam
2007-04-02 10:37
2007.05.06
Построение дерева исходного кода