是否有 Indy 服务器 属性 等同于 TCustomWinSocket.Data?

Is there an Indy server property equivalent to TCustomWinSocket.Data?

当我使用 TServerSocket 时,我可以使用 属性 Data 为每个客户端存储指向 class 的指针。

现在我将使用 Indy TIdCmdTCPServer,我想知道是否有等效的 属性。

是的,有 - TIdContext.Data属性。在为您提供 TIdCommand 参数而不是 TIdContext 参数的 TIdCmdTCPServer 事件中,您可以从 TIdCommand.Context 属性 访问 TIdContext 对象。例如:

type
  TMyClass = class
    // add whatever you need...
  end;

procedure TForm1.IdCmdTCPServer1Connect(AContext: TIdContext);
var
  MyCls: TMyClass;
begin
  MyCls := TMyClass.Create;
  // initialize MyCls as needed...
  AContext.Data := MyCls;
end;

procedure TForm1.IdCmdTCPServer1Disconnect(AContext: TIdContext);
begin
  AContext.Data.Free;
  AContext.Data := nil;
end;

procedure TForm1.IdCmdTCPServer1CommandHandlerCommand(ACommand: TIdCommand);
var
  MyCls: TMyClass;
begin
  MyCls := TMyClass(ACommand.Context.Data);
  // use MyCls as needed...
end;

Indy 还有另一个有用的功能。您可以从 TIdServerContext 派生自定义 class,向其中添加您想要的任何内容,然后在激活服务器之前将其分配给服务器的 ContextClass 属性。这样,当您需要访问您的自定义成员时,您可以简单地将任何 TIdContext 指针转换为您的 class 类型。例如:

type
  TMyContext = class(TIdServerContext)
  public
    // add whatever you need...
    constructor Create(AConnection: TIdTCPConnection; AYarn: TIdYarn; AList: TIdContextThreadList = nil); override;
    destructor Destroy; override;
  end;

constructor TMyContext.Create(AConnection: TIdTCPConnection; AYarn: TIdYarn; AList: TIdContextThreadList = nil);
begin
  inherited;
  //...
end;

destructor TMyContext.Destroy;
begin
  //...
  inherited;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  IdCmdTCPServer1.ContextsClass := TMyContext;
end;

procedure TForm1.IdCmdTCPServer1Connect(AContext: TIdContext);
var
  MyCtx: TMyContext;
begin
  MyCtx := TMyClass(AContext);
  // initialize MyCtx as needed...
end;

procedure TForm1.IdCmdTCPServer1CommandHandlerCommand(ACommand: TIdCommand);
var
  MyCtx: TMyContext;
begin
  MyCtx := TMyClass(ACommand.Context);
  // use MyCtx as needed...
end;

这样,当您可以使用服务器已经为您创建的客户端时,您无需浪费时间和内存为每个客户端分配单独的 class。