Using CallBack in Delphi

2

I'm rephrasing my question regarding the CallBack methodology.

I would like some example or specific material on how to use CallBacks calls from the server to the client.

Example:

CLIENT SIDE

On the client I have this TCallBack class

TCallback = class(TDBXCallBack)
  Function Execute(const Args: TJSONValue): TJSONValue; override;
  function GetConnectionName(OptionList: OleVariant): String;
  procedure ShowWaitScreen(const Msg: String);
  procedure ReleaseProcessScreen;
  function ShowProcessScreen(const ALinha: String; const ACaption: String;
                          APosition: Integer; ACount2: Integer;):  WordBool;
end;

With the code below, somewhere in the client, I send CallBack to the server.

Var
  FCallBack: TCallBack;
  ClientPx: TSMPrincipalClient;  
begin
  if (FCallBack = nil) then begin
     FCallBack := TCallBack.Create();
  end;
  try
    ClientPx := TSMPrincipalClient.Create(conDataSnap.DBXConnection, False);
    ClientPx.SetCallBack(FCallback);
  except
   on E:Exception do
    ExceptionMessage := e.Message;
  end;
end;

SERVER SIDE

As of now that is my doubt, the server has been called by the setCallback method

procedure TSMPrincipal.SetCallBack(CallBack: TDBXCallback);
var
  FCallBack: TDBXCallback;
begin
  FCallBack := CallBack;
  FConnection.ConnectionName := GetConnectionName;
  FConnection.Connected := True;
end;

At some point on the server I call the method on the client, how do I do this?

Result := FCallBack.GetConnectionName(Dataset.Data);
    
asked by anonymous 17.04.2014 / 17:08

1 answer

3

I found a tutorial well complete on Andreano Lanusse's blog.

When we have a client-server call involving some kind of processing, we use Callback to have the server send the processing status to the client. That said, you should follow these steps:

1 - Implement the server method. This server method receives a TDBXCallBack as parameter.

In the blog Andreano made a server method that backs up a database, returning the last row of the table that was processed to the client:

procedure TDSServerBatch.StartBackup(sMessage: TDBXCallback;
  sBackupFileName: String);
var
  LCallbackValue: TJSONObject;
  db: String;

begin

  db := DMServerContainer.GetEmployeeDBName;

  srvBackup.DatabaseName := Copy(db, Pos(':', db) + 1, Length(db));

  srvBackup.Attach;
  srvBackup.BackupFile.Add(sBackupFileName);

  srvBackup.ServiceStart;
  if srvBackup.Verbose then
    while not srvBackup.Eof do
    begin

      // if srvBackup.IsServiceRunning then
      begin
        LCallbackValue := TJSONObject.Create;
        LCallbackValue.AddPair(TJSONPair.Create('Server return',
            srvBackup.GetNextLine));

        sMessage.Execute(LCallbackValue);

      end;

    end;

  if srvBackup.Active then
    srvBackup.Detach();

end;

2- Implement the client-side.

I find it interesting to use anonymous methods for callback. Because? I explain: When using anonymous methods the callback reference to be executed will be passed from the server to the client whenever one of your server methods is executed. Here's the example below:

type
  TDSCallbackMethod = reference to function(const Args: TJSONValue): TJSONValue;

  TMessageCallback = class(TDBXCallback)
  private
    FCallBackMethod: TDSCallbackMethod;

  public
    constructor Create(CallBackMethod: TDSCallbackMethod);
    function Execute(const Arg: TJSONValue): TJSONValue; override;
  end;

implementation

constructor TMessageCallback.Create(CallBackMethod: TDSCallbackMethod);
begin
  FCallBackMethod := CallBackMethod;
end;

function TMessageCallback.Execute(const Arg: TJSONValue): TJSONValue;
begin
  Result := FCallbackMethod(Arg);
end;

3- To run the server method, you just need to do this:

//Declarar seu callback (Usei Métodos Anônimos)
callback := TMessageCallback.Create( function(const Args: TJSONValue) : TJSONValue;
//No caso, s é do tipo TDSServerBatchClient, que seria seu proxy em questão.
s := TDSServerBatchClient.Create(DMClientContainer.MyDSServer.DBXConnection);
s.StartBackup(callback, 'mybackup.ibk');

P.S .: Just to conclude, this response was based on the material taken from the blog. I just wrote to have a reference here on the site that does not depend on the link. I suggest you read the full post for better conclusions.

    
17.04.2014 / 19:04