gpt4 book ai didi

delphi - 使用 Delphi 和 Indy 10.6,我找不到 TIdServerContext 的 OnWork

转载 作者:行者123 更新时间:2023-12-02 14:07:04 25 4
gpt4 key购买 nike

在设置我的 TCP 客户端/服务器系统时,我对 TIdServerContext 进行了子类化以添加索引标志,但似乎没有 OnWork 事件。我需要重置计时器,例如在上传/下载大文件时,许多 Indy 组件都有一个专门用于此目的的 OnWork 事件,但我找不到用于 的计时器根据其他帖子,TIdServerContextTIdTCPServer 以及 TIdTCPServer.OnStatus 事件似乎未实现。

以下是我实现 TIdServerContext 的方法:

TUserContext = Class(TIdServerContext)
Protected
FUserID: Integer;
Public
Property UserID: Integer Read FUserID Write FUserID Default 0;
End;

Procedure FormCreate(Sender: TObject);
Begin
Server.ContextClass := TUserContext;
End;

Procedure ServerExecute(AContext: TIdContext);
Var
I: Integer;
Begin
I := TUserContext(AContext).UserID;
...
End;

最佳答案

OnWork... 事件位于 TIdComponent 类中,而 TIdServerContext 并非派生自该类。但是,TIdTCPConnectionTIdIOHandler 可以。 TIdContext 具有公共(public) Connection 属性,因此在服务器的事件(OnConnectOnExecute 等)中,您可以根据需要将处理程序分配给 TIdConnection.OnWork... 事件:

procedure TMyForm.ServerConnect(AContext: TIdContext);
begin
AContext.Connection.Tag := NativeInt(AContext);
AContext.Connection.OnWork := WorkHandler;
end;

procedure TMyForm.WorkHandler(ASender: TObject; AWorkMode: TWorkMode; AWorkCount: Int64);
var
Ctx: TUserContext;
begin
Ctx := TUserContext(TIdTCPConnection(ASender).Tag);
// use Ctx members as needed...
end;

或者,在不使用 Tag 的情况下将 AContext 传递给 WorkHandler 的另一种方法:

procedure TMyForm.ServerConnect(AContext: TIdContext);
var
Handler: TWorkEvent;
begin
Handler := WorkHandler;
TMethod(Handler).Data := AContext;
AContext.Connection.OnWork := Handler;
end;

procedure TMyForm.WorkHandler(ASender: TObject; AWorkMode: TWorkMode; AWorkCount: Int64);
var
Ctx: TUserContext;
begin
Ctx := TUserContext(Self);
// use Ctx members as needed...
end;

处理此问题的另一种方法是重写 TIdServerContext 构造函数,该构造函数接收 TIdTCPConnection 对象作为参数。您可以使处理程序成为 TUserContext 类本身的方法,并让其构造函数立即分配 OnWork... 事件,而不是等待服务器的 On首先触发的 (Connect|OnExecute) 事件:

type
TUserContext = Class(TIdServerContext)
protected
FUserID: Integer;
procedure WorkHandler(ASender: TObject; AWorkMode: TWorkMode; AWorkCount: Int64);
public
constructor Create(AConnection: TIdTCPConnection; AYarn: TIdYarn; AList: TIdContextThreadList = nil); override;
property UserID: Integer read FUserID write FUserID;
end;

constructor TUserContext.Create(AConnection: TIdTCPConnection; AYarn: TIdYarn; AList: TIdContextThreadList = nil);
begin
inherited;
AConnection.OnWork := WorkHandler;
end;

procedure TUserContext.WorkHandler(ASender: TObject; AWorkMode: TWorkMode; AWorkCount: Int64);
begin
// use Self members as needed...
end;

或者,如果您只需要按需举办事件:

type
TUserContext = Class(TIdServerContext)
protected
FUserID: Integer;
procedure WorkHandler(ASender: TObject; AWorkMode: TWorkMode; AWorkCount: Int64);
public
procedure StartWorkTimer;
procedure StopWorkTimer;
property UserID: Integer read FUserID write FUserID;
end;

procedure TUserContext.StartWorkTimer;
begin
Connection.OnWork := WorkHandler;
end;

procedure TUserContext.StopWorkTimer;
begin
Connection.OnWork := nil;
end;

procedure TMyForm.ServerExecute(AContext: TIdContext);
var
Ctx: TUserContext;
begin
Ctx := TUserContext(AContext);

...

if (some condition) then
Ctx.StartWorkTimer;

...

if (some other condition) then
Ctx.StopWorkTimer;

...
end;

关于delphi - 使用 Delphi 和 Indy 10.6,我找不到 TIdServerContext 的 OnWork,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43902374/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com