Конференция "Сети" » Проблема с закрытием IdTCPServer [WinXP]
 
  • Андрей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 пишет, что нет слушателя. Про какие именно тайм-ауты идёт речь?
  • 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;

    Теперь рубит всех и не виснет.
 
Конференция "Сети" » Проблема с закрытием IdTCPServer [WinXP]
Есть новые Нет новых   [134427   +34][b:0][p:0.001]