我的服务器端表单中有一个用户列表,成功登录后的每个用户都会添加到此列表中。我正在使用IdCmdTCPServer
来处理连接。
对于下一个操作或用户请求,我通过这种方式为每个用户分配了一个唯一ID(我使用了上下文绑定句柄)以进行连接标识:
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
!我现在无法检测哪个用户连接正在断开连接!
有没有想法检测断开用户上下文的句柄?