RTC Forums
November 24, 2024, 08:00:19 AM *
Welcome, Guest. Please login or register.

Login with username, password and session length
 
   Home   Help Login Register  
Pages: [1]
  Print  
Author Topic: Creating RTC components at runtime...  (Read 4769 times)
ClementDoss
RTC License
***
Posts: 36


« on: September 21, 2014, 11:27:25 PM »

Hi,

I'm still getting used to the components, so forgive me for asking such newbie questions  Grin

I'd like to create a base class where I will derive some API functions.

Code:
  TmdwClientModule = class
  private
    function GetModuleFileName: String;
    function GetModuleHost: String;

  protected
    FClientModule : TrtcClientModule; // I'd like to move this fellow to private
    procedure SetModuleFileName(const Value: String);
    procedure SetModuleHost(const Value: String);

    function DoExecute( aInfo : TRtcFunctionInfo ) : TRtcValue; // I would like to call this one!
  public
    constructor Create( aRtcDataClient : TrtcDataClient ); virtual;
    destructor Destroy; override;

    property ModuleFileName : String read GetModuleFileName;
    property ModuleHost : String read GetModuleHost;

  end;

And for example the modules would use somthing like :

Code:
  TmdwClientModule_Authentication = Class( TmdwClientModule )
  public
    constructor Create(aRtcDataClient: TRtcDataClient); override;

    function AuthorizeUser( const aLogin, aPwd : String ) : Boolean;
    {.. All the other functions for authentication .. }
  End;


The application will call AuthorizeUser with the login and Password the user typed in. How should I write the AuthorizeUser function?
I would like it to use the "DoExecute" parent method. With this approach I want to centralize all my synchronized calls.

Code:
function TmdwClientModule_Authentication.AuthorizeUser(const aLogin,
  aPwd: String): Boolean;
var
  RC : TRtcFunctionInfo;
  Retval : TRtcValue;
begin
     RC := FClientModule.NewFunction('Login');
     RC.AsParam['Login'] := aLogin;
     RC.AsParam['PWD'] := aPwd;
     Retval := FClientModule.Execute;
     // Here I want to check if the results is valid not call directly... ex: No exception was raised
     // That's one reason to use "DoExecute"
     Result := Retval.AsBoolean;
end;

And I would like to implement a DoExecuteAsync with an anominous method which will use TRtcResult "somehow" .

Am I completely out of line?  Undecided
Do you have some example?  Huh

Best regards,
Clément
Logged
D.Tkalcec (RTC)
Administrator
*****
Posts: 1881


« Reply #1 on: September 22, 2014, 12:10:11 AM »

The Execute method on the TRtcClientModule component is always blocking. The code you have implemented looks fine for blocking execution, provided you set up the connection component properly and link components properly, as explained in Quick Start examples. I'm not sure what you want to do with anonymous methods, though. You have your own class, so you can declare a normal method on your class and assign that method to the OnResult event of a TRtcResult component, which you would create in code and use as parameter to the asynchsonous Call method on the TRtcClientModule component.

Best Regards,
Danijel Tkalcec
Logged
ClementDoss
RTC License
***
Posts: 36


« Reply #2 on: September 22, 2014, 05:29:02 PM »


Well,
  the Execute ( Blocking ) will be used for some API functions that will require the client to wait and continue.
For this login example I have some checking to do before actually displaying the main form. Would you use non-blocking call?
how would you do?

I'm still new to RTC, and I'm reading all the examples and samples. But I'm still confuse of when to use TrtcResult. I have a form with 4 lookup datasets. I would like load this form data asynchronously. So I would create one RTCResult per async call. And I would assign the same OnReturn Event for all of them. Is this the correct way to do it? When I thought of anominous method I was trying to solve this calling issue.

Still about this form..  THe "DoShow" procedure will look like this:
procedure TMyForm.DoShow;
begin
  DoLoadLookup_TicketTypes;
  DoLoadLookup_CustomerTypes;
  DoLoadLookup_Prices;
  inherited;
end;

Each one of these procedures will call a remote function that will return a Dataset, and inside them the dataset will be assigned to the corresponding control.
Do I have to set my ThhtpClient.MultiThreaded to True? If I don't set it, what would happen?
Is there a way to wait for all the calls to return and then display the form, something like:

procedure TMyForm.DoShow;
begin
  DoLoadLookup_TicketTypes;
  DoLoadLookup_CustomerTypes;
  DoLoadLookup_Prices;
  DoWaitForIt; // After all three calls return, inherited will be called.
  inherited;
end;

TIA,
Clément


Clément
Logged
D.Tkalcec (RTC)
Administrator
*****
Posts: 1881


« Reply #3 on: September 22, 2014, 07:30:56 PM »

When you are using remote functions in asynchronous mode, which means using a TRtcResult component with an implemented OnResult event and a Call method instead of Execute, the OnResult event of the TRtcResult component will be called when the Client receives a result from the Server for the remote function sent to the Server. If you send multiple remote function calls to the Server by using the same TRtcHttpClient component, they will be sent serialized, one after the other, with result arriving in the exact same order in the OnResult events of the TRtcREsult components used as parameters in the Call method when posting the remote function call.

Using a MultiThreaded connection does not mean that all your remote function calls will be sent at the same time, though. It only that all communication (sending and receiving data), along with all the associated events triggered by the connection components, will be executing in a background thread. When using a blocking connection provider (like WinInet or WinHTTP), this will make sure that your Main Thread remains "unblocked", so your users won't see the "Application not Responding" message during the communication process. You will, however, need to make sure the user can not do something stupid while waiting for responses from the Server, since from a User perspective, an Appication which is communicating asynchronously with the Server may seem like it's "idle".

If you want to block the user interface and force the user to wait for all the calls to return, even though you were using the TRtcResult component and the Call method, you can use the WaitForCompletion method, which is available on the TRtcHttpClient component.

Best Regards,
Danijel Tkalcec
Logged
Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.21 | SMF © 2015, Simple Machines Valid XHTML 1.0! Valid CSS!
Page created in 0.025 seconds with 16 queries.