Как определить, какой клиент отключен в TCP-соединении?

У меня есть список пользователей в моей серверной форме, который каждый пользователь после успешного входа будет добавлен в этот список. я использую IdCmdTCPServer для обработки соединений. Для следующих операций или пользовательских запросов я назначил уникальный идентификатор (я использовал дескриптор привязки контекста) каждому пользователю для идентификации соединения следующим образом:

procedure TForm1.IdCmdTCPServer1CommandHandlers2Command(ASender: TIdCommand);
var                 // Login Command Handler
  sUsername,
  sPassword: string;
begin
  sUsername := ASender.Context.Connection.Socket.ReadLn;
  sPassword := ASender.Context.Connection.Socket.ReadLn;

  if sUsername = sPassword then    // for example!
  begin
    Inc(UsersCount);
    SetLength(Users, UsersCount);

    with Users[UsersCount - 1] do
    begin
      Username := sUsername;
      ID := ASender.Context.Connection.Socket.Binding.Handle;

      ASender.Context.Connection.Socket.WriteLn(IntToStr(ID));
    end;

    Memo1.Lines.Append('User Logged In: ' + sUsername + ' from ' + ASender.Context.
      Connection.Socket.Binding.PeerIP + ' (' + IntToStr(ASender.Context.Connection.
      Socket.Binding.Handle) + ')');
  end
  else
  begin
    ASender.Context.Connection.Socket.WriteLn('-1'); // -1 means username is not mach to password (wrong user or pass error)

    Memo1.Lines.Append('User Login Fails: ' + sUsername + ' from ' + ASender.Context.
      Connection.Socket.Binding.PeerIP + ' (' + IntToStr(ASender.Context.Connection.
      Socket.Binding.Handle) + ')');

    ASender.Context.Connection.Disconnect;
  end;
end;

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

procedure TForm1.IdCmdTCPServer1Disconnect(AContext: TIdContext);
var
  i,
  UserID: Integer;
begin
  UserID := AContext.Connection.Socket.Binding.Handle;

  Memo1.Lines.Append('Disconnected from ' + AContext.Binding.PeerIP + ':' +
    IntToStr(UserID));


  // eliminating user from list
  i := 0;
  while i < UsersCount do
    if Users[i].ID = UserID then
    begin
      Users[i].ID := -11; // ignore this user in next user operations
      Break;
    end
    else
      Inc(i);
end;

Проблема здесь в том, что когда соединение с контекстом отключается, Handle свойство будет присвоено -1 автоматически! и я не могу определить, какое пользовательское соединение отключается сейчас!

Есть ли идея обнаружить отключение дескриптора пользовательского контекста?

0 ответов

Другие вопросы по тегам