Как определить, какой клиент отключен в 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
автоматически! и я не могу определить, какое пользовательское соединение отключается сейчас!
Есть ли идея обнаружить отключение дескриптора пользовательского контекста?