Мастера DELPHI, Delphi programming community Рейтинг@Mail.ru Титульная страница Поиск, карта сайта Написать письмо 
| Новости |
Новости сайта
Поиск |
Поиск по лучшим сайтам о Delphi
FAQ |
Огромная база часто задаваемых вопросов и, конечно же, ответы к ним ;)
Статьи |
Подборка статей на самые разные темы. Все о DELPHI
Книги |
Новинки книжного рынка
Новости VCL
Обзор свежих компонент со всего мира, по-русски!
|
| Форумы
Здесь вы можете задать свой вопрос и наверняка получите ответ
| ЧАТ |
Место для общения :)
Орешник |
Коллекция курьезных вопросов из форумов
KOL и MCK |
KOL и MCK - Компактные программы на Delphi
Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / rsdn.org

 
Чтобы не потерять эту дискуссию, сделайте закладку « предыдущая ветвь | форум | следующая ветвь »

Проблема с закрытием IdTCPServer [WinXP]


Андрей0508   (05.08.12 15:31

Добрый день.
Делается на Indy 10, Delphi 2009.

Проблема следующая. Если попытаться сделать IdTCPServer1.Active := False; приложение виснет наглухо.
Почитав интернет решил сделать отключение всех подключений перед остановкой. Код:
function TMainForm.CloseAllConnections: Boolean;
var
  i: Integer;
begin
 Result := True;
 if IdTCPServer1.Contexts <> nil then
   begin
     with IdTCPServer1.Contexts.LockList do
       begin
         if Count > 0 then
           ProgLog('Server close all connection before stop');
         try
            for i := 0 to Count - 1 do
               begin
                 TIdContext(Items[i]).Connection.Disconnect(False);
               end;
         finally
                IdTCPServer1.Contexts.UnlockList;
         end;
       end;
   end;
end;

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

Пробовал в OnExecute сервер делать:
AContext.Connection.Socket.Close; Закрывает любое соединение.

Подскажите, пож-та, как отключить все соединения корректно.
Заранее благодарю.


Андрей0508   (05.08.12 21:23[1]

Уточнение. Соединения отключает и после этого зависает.


brother ©   (05.08.12 22:33[2]

на долго? что с таймаутами?


Андрей0508   (06.08.12 20:02[3]

Засек время. После 5 минут висит. При попытке подключиться к нему (во время висения), виснет клиент, который на Indy10. Подключаясь через пакет utl_tcp Oracle пишет, что нет слушателя. Про какие именно тайм-ауты идёт речь?


sniknik ©   (07.08.12 00:20[4]

попробуй шедулер потоков поставить явно (TIdSchedulerOfThreadDefault) и перед закрытием делать
Server.Scheduler.AcquireYarn;
Server.Active := false;
(видел в исходниках инди, разрешает исключения, судя по коментарию, а разрыв коннекта сервером это явно исключение)


Андрей0508   (07.08.12 17:59[5]

Спасибо. Частично помогло. Теперь виснет через раз :(

Использую TIdTCPServer, TIdAntiFreeze, TIdSchedulerOfThreadDefault

Изначально взял это из примера Indy10. Он кстати, тоже виснет:)


sniknik ©   (07.08.12 20:36[6]

> Теперь виснет через раз :(
похоже зависит от того в каком месте обработка текущих соединений...

а если "радикально",  Server.Free; ??? вместо Server.Active := false;
ну, вылезет ексепт, заблокировать да и все, лишь бы не висело.


sniknik ©   (07.08.12 20:54[7]

или вот еще проверить  
Server.Scheduler.ActiveYarns.Clear; //AcquireYarn;


Андрей0508   (08.08.12 20:28[8]

> Server.Scheduler.ActiveYarns.Clear; //AcquireYarn;

Вот так все вообще отлично. Протестил раз 15. Даже вариант, когда все соединения, что-то передают серверу. Отключает всех на ура. Спасибо большое sniknik! ;)


Валерий   (04.12.12 21:15[9]

Привет. А я пользуюсь кодом из первого сообщения и все ок. Подскажите, пож-та, как на стороне сервера проверять отключившиеся соединения, но которые еще числятся на сервере(т.е. поток есть и событие onDissconnect не сработало)? Спасибо


brother ©   (18.02.13 10:53[10]

"спросить" клиента - нет овета - отрубаем его


BondFx ©   (17.11.16 01:02[11]

Для Indy 9 проверка на дисконнект:

procedure TfrmMain.ServerExecute(AThread: TIdPeerThread);
begin
Athread.Connection.CheckForDisconnect(False, True);
if Athread.Connection.Connected then begin
....
end;
end;


BondFX ©   (17.11.16 01:02[12]

Для Indy 9 проверка на дисконнект:

procedure TfrmMain.ServerExecute(AThread: TIdPeerThread);
begin
Athread.Connection.CheckForDisconnect(False, True);
if Athread.Connection.Connected then begin
....
end;
end;


BondFX ©   (17.11.16 01:03[13]

Для Indy 9 проверка на дисконнект:

procedure TfrmMain.ServerExecute(AThread: TIdPeerThread);
begin
Athread.Connection.CheckForDisconnect(False, True);
if Athread.Connection.Connected then begin
....
end;
end;


BondFX ©   (17.11.16 02:46[14]

Теперь вылезла проблема при слишком частых запросах к серверу. Опять завис. Пока отключаю 10 клиентов приходит запрос на новое подключение (через 0,03 секунды). Проблему решил радикально:
На обработчик OnClose формы:

List:= Server.Threads.LockList;
Server.OnExecute:= nil;
Server.OnConnect:= nil;
Server.OnDisconnect:= nil;
try
 for I:= 0 to List.Count - 1 do TIdPeerThread(List[I]).Connection.Disconnect;
finally
 Server.Threads.UnlockList;
end;
Server.Active:= False;

Теперь рубит всех и не виснет.


версия для печати

Написать ответ

Ваше имя (регистрация  E-mail 







Разрешается использование тегов форматирования текста:
<b>жирный</b> <i>наклонный</i> <u>подчеркнутый</u>,
а для выделения текста программ, используйте <code> ... </code>
и не забывайте закрывать теги! </b></i></u></code> :)


Наверх

  Рейтинг@Mail.ru     Титульная страница Поиск, карта сайта Написать письмо