使用 Delphi 和 Indy 10.6 我找不到 TIdServerContext 的 OnWork
With Delphi and Indy 10.6 I can't find OnWork for TIdServerContext
在设置我的 TCP Client/Server 系统时,我将 TIdServerContext
子类化以添加索引标志,但似乎没有 OnWork
事件。我需要重置一个计时器,比如说 uploading/downloading 一个大文件,很多 Indy 组件都有一个 OnWork
事件适合这个,但我找不到 TIdServerContext
或 TIdTCPServer
,根据其他帖子,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
class 中,TIdServerContext
不是从中派生的。但是,TIdTCPConnection
和 TIdIOHandler
可以。 TIdContext
有一个 public Connection
属性,因此在您服务器的事件(OnConnect
、OnExecute
等)中,您可以将处理程序分配给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
class 本身的方法,并让它的构造函数立即分配 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;
在设置我的 TCP Client/Server 系统时,我将 TIdServerContext
子类化以添加索引标志,但似乎没有 OnWork
事件。我需要重置一个计时器,比如说 uploading/downloading 一个大文件,很多 Indy 组件都有一个 OnWork
事件适合这个,但我找不到 TIdServerContext
或 TIdTCPServer
,根据其他帖子,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
class 中,TIdServerContext
不是从中派生的。但是,TIdTCPConnection
和 TIdIOHandler
可以。 TIdContext
有一个 public Connection
属性,因此在您服务器的事件(OnConnect
、OnExecute
等)中,您可以将处理程序分配给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
class 本身的方法,并让它的构造函数立即分配 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;