-
Андрей0508 (05.08.12 15:31) [0]Добрый день.
Делается на 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 пишет, что нет слушателя. Про какие именно тайм-ауты идёт речь?
-
попробуй шедулер потоков поставить явно (TIdSchedulerOfThreadDefault) и перед закрытием делать
Server.Scheduler.AcquireYarn;
Server.Active := false;
(видел в исходниках инди, разрешает исключения, судя по коментарию, а разрыв коннекта сервером это явно исключение) -
Андрей0508 (07.08.12 17:59) [5]Спасибо. Частично помогло. Теперь виснет через раз :(
Использую TIdTCPServer, TIdAntiFreeze, TIdSchedulerOfThreadDefault
Изначально взял это из примера Indy10. Он кстати, тоже виснет:) -
> Теперь виснет через раз :(
похоже зависит от того в каком месте обработка текущих соединений...
а если "радикально", Server.Free; ??? вместо Server.Active := false;
ну, вылезет ексепт, заблокировать да и все, лишь бы не висело. -
или вот еще проверить
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]"спросить" клиента - нет овета - отрубаем его
-
Для Indy 9 проверка на дисконнект:
procedure TfrmMain.ServerExecute(AThread: TIdPeerThread);
begin
Athread.Connection.CheckForDisconnect(False, True);
if Athread.Connection.Connected then begin
....
end;
end; -
Для Indy 9 проверка на дисконнект:
procedure TfrmMain.ServerExecute(AThread: TIdPeerThread);
begin
Athread.Connection.CheckForDisconnect(False, True);
if Athread.Connection.Connected then begin
....
end;
end; -
Для Indy 9 проверка на дисконнект:
procedure TfrmMain.ServerExecute(AThread: TIdPeerThread);
begin
Athread.Connection.CheckForDisconnect(False, True);
if Athread.Connection.Connected then begin
....
end;
end; -
Теперь вылезла проблема при слишком частых запросах к серверу. Опять завис. Пока отключаю 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;
Теперь рубит всех и не виснет.