2017-05-10 9 views
1

TCP 클라이언트/서버 시스템을 설정할 때 TIdServerContext을 서브 클래 싱하여 인덱스 플래그를 추가했지만 OnWork 이벤트가없는 것 같습니다. 큰 파일을 업로드/다운로드하는 동안 타이머를 재설정해야하고 많은 인디 구성 요소에 OnWork 이벤트가 있지만, TIdServerContext 또는 TIdTCPServer에 대한 이벤트를 찾을 수없고 TIdTCPServer.OnStatus 이벤트가 나타납니다. 다른 게시물에 따르면, 구현되지 않았습니다.Delphi 및 Indy 사용 10.6 TIdServerContext 용 OnWork를 찾을 수 없습니다.

는 여기가 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; 

답변

2

OnWork... 이벤트는 TIdServerContext에서 파생되지 않습니다는 TIdComponent 클래스에 있습니다. 그러나 TIdTCPConnectionTIdIOHandler 않습니다. Tag를 사용하지 않고 WorkHandlerAContext를 전달하는 다른 방법을

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; 

을 또는 : 당신은 필요에 따라 TIdConnection.OnWork... 이벤트에 핸들러를 할당 할 수있는 서버의 이벤트 (OnConnect, OnExecute 등)에 있도록 TIdContext는 공공 Connection 속성이 있습니다 :

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; 

이 처리하는 또 다른 방법은 매개 변수로 TIdTCPConnection 객체를 수신 TIdServerContext 생성자를 무시한다. 당신은 당신의 핸들러가 TUserContext 클래스 자체의 방법이 될 수 있도록, 그 생성자 대신 첫번째 발사 서버의 On(Connect|OnExecute) 이벤트를 기다리는 즉시 OnWork... 이벤트를 할당 할 수 : 방금 이벤트를 필요로하는 경우,

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; 
+0

덕분에,이 내가 할 수 있지만 여러 클라이언트를 허용하고있어, 각 TIdServerContext 내가 처리되고있는 사용자가 알 수 있도록 사용자 ID를 가지고 있으며, 각 사용자가 자신의 타이머를 가지고 integer 재설정해야하므로 해당 연결에 대한 UserID를 OnWork 이벤트에 전달할 수 있어야합니다. 그 점에 대해서 아직 조금 불분명하다. – Skutch

+0

'OnWork ... '핸들러를'TUserContext' 클래스의 멤버 메소드로 만들면 클라이언트별로 처리되고'TUserContext' 객체의'Self' 포인터에 액세스하여 데이터 멤버에 액세스합니다 필요에 따라. 나는 나의 대답을 업데이트했다. –

+0

당신 Remy, 고마워요;) – Skutch