📄 rtcdatacli.pas
字号:
FAutoSync: boolean;
protected
// @exclude
function GetClient: TRtcDataClient; virtual;
// @exclude
procedure SetClient(const Value: TRtcDataClient); virtual;
// @exclude
function GetLink: TRtcDataClientLink; virtual;
// @exclude
procedure SetLink(const Value: TRtcDataClientLink); virtual;
// @exclude
procedure Call_BeginRequest(Sender:TRtcConnection); virtual; abstract;
// @exclude
procedure Call_ResponseDone(Sender:TRtcConnection); virtual; abstract;
// @exclude
procedure Call_ResponseData(Sender:TRtcConnection); virtual; abstract;
// @exclude
procedure Call_ResponseAbort(Sender:TRtcConnection); virtual; abstract;
// @exclude
procedure Call_ResponseReject(Sender:TRtcConnection); virtual; abstract;
// @exclude
procedure Call_SessionOpen(Sender:TRtcConnection); virtual; abstract;
// @exclude
procedure Call_SessionClose(Sender:TRtcConnection); virtual; abstract;
// @exclude
procedure Call_DataReceived(Sender:TRtcConnection); virtual; abstract;
// @exclude
procedure Call_DataOut(Sender:TRtcConnection); virtual; abstract;
// @exclude
procedure Call_DataIn(Sender:TRtcConnection); virtual; abstract;
// @exclude
procedure Call_DataSent(Sender:TRtcConnection); virtual; abstract;
// @exclude
procedure Call_ReadyToSend(Sender:TRtcConnection); virtual; abstract;
// @exclude
procedure Call_ConnectLost(Sender:TRtcConnection); virtual; abstract;
// @exclude
procedure Call_RepostCheck(Sender:TRtcConnection); virtual; abstract;
// Post a new Request Object
procedure PostRequest(Req:TRtcClientRequestInfo; FromInsideEvent:boolean=False); virtual;
{ Insert a Request before active request.
This procedure may ONLY be called from BeginRequest event
to place another request before the active request. }
procedure InsertRequest(Req:TRtcClientRequestInfo); virtual;
public
// @exclude
constructor Create(AOwner:TComponent); override;
// @exclude
destructor Destroy; override;
// Skip all requests posted to the Client Connection used (RequestAborted events will NOT BE triggered!!!)
procedure SkipRequests; virtual;
// Cancel all requests posted to the Client Connection used and fire RequestAborted events
procedure CancelRequests; virtual;
// Check request count at Client Connection used (number of requests waiting to be processed)
function RequestCount:integer; virtual;
// Wait for all posted requests and function calls to complete,
// be aborted, be calceled, or for the connection to close. @html(<br>)
// Using a timeout (seconds) you can specify how long you want to wait.
// (0=forever). Returns TRUE only if there are no more requests waiting.
// Returns FALSE if timed-out or terminating or connection can't be open
// or connection closed on purpose.
function WaitForCompletion(UserInteractionAllowed:boolean=False; Timeout:cardinal=0):boolean; virtual;
published
{ If all events which your component implements have to access the GUI,
to avoid checking the "Sender.inMainThread" and calling Sender.Sync(Event)
for every event, you can se this AutoSyncEvent property to true,
which will ensure that any event assigned to this component will
be called from the main thread (synchronized, when needed). }
property AutoSyncEvents:boolean read FAutoSync write FAutoSync default false;
{ You can link your components (one or more) to a DataClientLink component
by assigning your @Link(TRtcDataClientLink) component to chind component's Link property.
Doing this, you only have to set the Client property for the master
DataClientLink component and don't need to do it for every single
DataRequest component. }
property Link:TRtcDataClientLink read GetLink write SetLink;
{ You can also link your components (one or more) directly to your
DataClient connection component by assigning your
@Link(TRtcDataClient) connection component to this child component's Client property.
This is useful if you don't want to use a DataClientLink. }
property Client:TRtcDataClient read GetClient write SetClient;
end;
{ @abstract(DataClient Link, used to group Data Requests)
You can use TRtcDataClientLink components to group several related
@Link(TRtcDataRequest) components. Simply set this component as the
Link property for all your RtcDataSource components, so that
you don't have to set the Client property for every single
TRtcDataRequest component separately. This is useful especially
when the component is used in a datamodule or a form without
DataClient and you need to link all the components to
a DataClient which is on another datamodule or form.
@html(<br><br>)
Check @Link(TRtcAbsDataClientLink) for more info. }
TRtcDataClientLink=class(TRtcAbsDataClientLink)
private
FOnBeginRequest:TRtcNotifyEvent;
FOnResponseDone:TRtcNotifyEvent;
FOnResponseData:TRtcNotifyEvent;
FOnResponseAbort:TRtcNotifyEvent;
FOnResponseReject:TRtcNotifyEvent;
FOnSessionOpen:TRtcNotifyEvent;
FOnSessionClose:TRtcNotifyEvent;
FOnRepostCheck:TRtcNotifyEvent;
protected
// @exclude
FDataClientLinks:TRtcDataClientLinkList;
// @exclude
procedure Call_DataReceived(Sender:TRtcConnection); override;
// @exclude
procedure Call_DataOut(Sender:TRtcConnection); override;
// @exclude
procedure Call_DataIn(Sender:TRtcConnection); override;
// @exclude
procedure Call_DataSent(Sender:TRtcConnection); override;
// @exclude
procedure Call_ReadyToSend(Sender:TRtcConnection); override;
// @exclude
procedure Call_ConnectLost(Sender:TRtcConnection); override;
// @exclude
procedure AddChildLink(Value:TRtcAbsDataClientLink);
// @exclude
procedure RemoveChildLink(Value:TRtcAbsDataClientLink);
// @exclude
procedure RemoveAllChildLinks;
public
// @exclude
constructor Create(AOwner:TComponent); override;
// @exclude
destructor Destroy; override;
// @exclude
procedure Call_BeginRequest(Sender:TRtcConnection); override;
// @exclude
procedure Call_ResponseDone(Sender:TRtcConnection); override;
// @exclude
procedure Call_ResponseData(Sender:TRtcConnection); override;
// @exclude
procedure Call_ResponseAbort(Sender:TRtcConnection); override;
// @exclude
procedure Call_ResponseReject(Sender:TRtcConnection); override;
// @exclude
procedure Call_RepostCheck(Sender:TRtcConnection); override;
// @exclude
procedure Call_SessionOpen(Sender:TRtcConnection); override;
// @exclude
procedure Call_SessionClose(Sender:TRtcConnection); override;
published
{ Use this event to initialize child requests linked to this DataLink }
property OnBeginRequest:TRtcNotifyEvent read FOnBeginRequest write FOnBeginRequest;
{ Use this event to add additional control after each OnDataReceived package. }
property OnResponseData:TRtcNotifyEvent read FOnResponseData write FOnResponseData;
{ Use this event to finalize child requests linked to this DataLink }
property OnResponseDone:TRtcNotifyEvent read FOnResponseDone write FOnResponseDone;
{ Called after OnConnectLost, OnConnectFail and OnConnectError if request is not finished and not marked for reposting }
property OnRepostCheck:TRtcNotifyEvent read FOnRepostCheck write FOnRepostCheck;
{ Called after OnRepostCheck if request is not finished and is not marked for reposting. }
property OnResponseAbort:TRtcNotifyEvent read FOnResponseAbort write FOnResponseAbort;
{ Called after Response has been rejected by calling Response.Reject }
property OnResponseReject:TRtcNotifyEvent read FOnResponseReject write FOnResponseReject;
{ Called after a new Session has been opened. }
property OnSessionOpen:TRtcNotifyEvent read FOnSessionOpen write FOnSessionOpen;
{ Called before an existing session is about to be closed. }
property OnSessionClose:TRtcNotifyEvent read FOnSessionClose write FOnSessionClose;
end;
{ @abstract(DataRequest Info Object)
This object is created and filled by TRtcDataRequest,
when you Post or Insert a DataRequest.
@exclude }
TRtcDataRequestInfo=class(TRtcClientRequestInfo)
protected
// @exclude
FRequest:TRtcClientRequest;
// @exclude
FEvents:TRtcAbsDataClientLink;
public
// @exclude
procedure Call_BeginRequest(Sender:TRtcConnection); override;
// @exclude
procedure Call_ResponseData(Sender:TRtcConnection); override;
// @exclude
procedure Call_ResponseDone(Sender:TRtcConnection); override;
// @exclude
procedure Call_ResponseAbort(Sender:TRtcConnection); override;
// @exclude
procedure Call_ResponseReject(Sender:TRtcConnection); override;
// @exclude
procedure Call_SessionOpen(Sender:TRtcConnection); override;
// @exclude
procedure Call_SessionClose(Sender:TRtcConnection); override;
// @exclude
procedure Call_DataReceived(Sender:TRtcConnection); override;
// @exclude
procedure Call_DataOut(Sender:TRtcConnection); override;
// @exclude
procedure Call_DataIn(Sender:TRtcConnection); override;
// @exclude
procedure Call_DataSent(Sender:TRtcConnection); override;
// @exclude
procedure Call_ReadyToSend(Sender:TRtcConnection); override;
// @exclude
procedure Call_ConnectLost(Sender:TRtcConnection); override;
// @exclude
procedure Call_RepostCheck(Sender:TRtcConnection); override;
// @exclude
function Get_Request:TRtcClientRequest; override;
public
// Standard constructor
constructor Create; virtual;
// @exclude
destructor Destroy; override;
{ Request Info, will be destroyed after the Request has been processed,
has to be assigned a valid TRtcClientRequest object before posting. }
property Request:TRtcClientRequest read FRequest write FRequest;
{ This DataClient Link component will be used to call events. }
property Events:TRtcAbsDataClientLink read FEvents write FEvents;
end;
// @exclude
TRtcDataRequestData=class
public
FRequest:TRtcClientRequest;
constructor Create; virtual;
destructor Destroy; override;
end;
{ @abstract(Data Request, used to Prepare+Post or Insert+Prepare Requests for DataClient)
This is the component you have to use to work with DataClient.
Put TRtcDataRequest on a form or a datamodule and define events
at design-time, which will be used for default request processing.
@html(<br><br>)
Then, at runtime, there are 2 ways you can use this DataRequest:
@html(<br>)
1.) From the Main thread, you can prepare the request using the
@Link(TRtcDataRequest.Request) property and call @link(TRtcDataRequest.Post)
to post the prepared request to its associated DataClient, or ...
@html(<br>)
2.) From inside a BeginRequest event handler (which is called by the DataClient
connection component), you can insert this DataRequest, so that your active
DataRequest is put on the 2nd position and this request is put on the first
place, by calling the @Link(TRtcDataRequest.Insert) method. After calling
@link(TRtcDataRequest.Insert), immediatelly a new @Link(TRtcDataClient.Request)
is created for this inserted DataRequest, so you can initialize the request
before exiting your event handler.
@html(<br><br>)
Check @Link(TRtcAbsDataClientLink) for more info. }
TRtcDataRequest=class(TRtcAbsDataClientLink)
private
FCS:TRtcCritSec;
FMyData:TObjList;
FMainThrData:TRtcDataRequestData;
FHyperThreading: boolean;
function CheckMyData:TRtcDataRequestData;
function GetMyData:TRtcDataRequestData;
procedure ClearMyData;
function GetRequest: TRtcClientRequest;
protected
// @exclude
FAutoRepost:integer;
// @exclude
FOnBeginRequest: TRtcNotifyEvent;
// @exclude
FOnResponseData: TRtcNotifyEvent;
// @exclude
FOnResponseDone: TRtcNotifyEvent;
// @exclude
FOnResponseAbort: TRtcNotifyEvent;
// @exclude
FOnResponseReject: TRtcNotifyEvent;
// @exclude
FOnSessionOpen: TRtcNotifyEvent;
// @exclude
FOnSessionClose: TRtcNotifyEvent;
// @exclude
FOnConnectLost: TRtcNotifyEvent;
// @exclude
FOnDataReceived: TRtcNotifyEvent;
// @exclude
FOnReadyToSend: TRtcNotifyEvent;
// @exclude
FOnDataOut: TRtcNotifyEvent;
// @exclude
FOnDataIn: TRtcNotifyEvent;
// @exclude
FOnDataSent: TRtcNotifyEvent;
// @exclude
FOnRepostCheck: TRtcNotifyEvent;
// @exclude
procedure Call_BeginRequest(Sender:TRtcConnection); override;
// @exclude
procedure Call_ResponseData(Sender:TRtcConnection); override;
// @exclude
procedure Call_ResponseDone(Sender:TRtcConnection); override;
// @exclude
procedure Call_ResponseAbort(Sender:TRtcConnection); override;
// @exclude
procedure Call_ResponseReject(Sender:TRtcConnection); override;
// @exclude
procedure Call_SessionOpen(Sender:TRtcConnection); override;
// @exclude
procedure Call_SessionClose(Sender:TRtcConnection); override;
// @exclude
procedure Call_DataReceived(Sender:TRtcConnection); override;
// @exclude
procedure Call_DataOut(Sender:TRtcConnection); override;
// @exclude
procedure Call_DataIn(Sender:TRtcConnection); override;
// @exclude
procedure Call_DataSent(Sender:TRtcConnection); override;
// @exclude
procedure Call_ReadyToSend(Sender:TRtcConnection); override;
// @exclude
procedure Call_ConnectLost(Sender:TRtcConnection); override;
// @exclude
procedure Call_RepostCheck(Sender:TRtcConnection); override;
public
// @exclude
constructor Create(AOwner:TComponent); override;
// @exclude
destructor Destroy; override;
{ Post this DataRequest to assigned DataClient.
@html(<br><br>)
After a call to Post, an object will be created to hold the
prepared Request info, after which the Request property will be cleared,
so that you can prepare and post new requests immediatelly,
without waiting for the last request to complete.
@html(<br><br>)
When posting a new Request from inside an Event of a running request/response loop,
always call the method with "FromInsideEvent" parameter set to TRUE.
Events assigned to this TRtcDataRequest will not be removed nor cleared,
so you can define them at design-time and not worry about them at runtime. }
procedure Post(FromInsideEvent:boolean=False); virtual;
{ Insert this request before the active request.
@html(<br><br>)
DataRequest objects which are used for automatic initialisation
can be inserted before the active request, but ONLY from inside
the active request's BeginRequest event handler. After calling
this Insert procedure, a new Request is created for the inserted
DataRequest and can/should be modified/prepared before exiting the
BeginRequest event. After BeginRequest event exists, the inserted
DataRequest's BeginRequest events will be called, as if this event
was posted before the one that inserted it. }
procedure Insert; virtual;
{ ONLY use this Request property to prepare a request BEFORE posting.
@html(<br>)
DO NOT directly use this property when processing the request.
After a request has been posted, it is moved to the DataClient,
so you can access it (from events) using Sender's Request property. }
property Request:TRtcClientRequest read GetRequest;
published
{ If you want to enable the possibility to use this Data Request to send requests
from multiple threads AT THE SAME TIME, where this component will acs as if
it were X components, one for each thread, simply set HyperThreading to TRUE. @html(<br><br>)
This is useful if you need to send requests to another Server from
within your Server running in multi-threaded mode and want to use only one set of
rtcHttpClient/rtcDataRequest components for all clients connected to your Server.
Even in HyperThreading mode, only properties and methods needed to prepare and post
the request (Request and Post) will use a separate copy for each thread, while all
other properties and methods exist only once for all threads, so don't try to modify
them while your application is actively using the component in multi-threaded mode. @html(<br><br>)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -