title: Delphi - Asynchronous Datasnap Method Calls
body: <p>I'm writing a Datasnap application with a TCP connection between client/server, with the server connected to an SQL server.</p>
  
  <p><strong>Server</strong> has a datamodule DM1 with all dataset queries and SQL connection. The DM1 also has REST request/client/response components.</p>
  
  <p>DM1 has an exposed function PostDataAsync with ID param: to generate a json from a dataset, then HTTP post it to a RESTFul service. It returns the number of records failed to post in the callback arg.</p>
  
  <p>The DSServer of this DM1 is “Invocation”.</p>
  
  <p>The invocation server type should ensure that each server method call has its own DB connection, dataset, Rest components, which will not have multiple calls interfere with the data of each other (if added parallel threading).</p>
  
  <pre><code>procedure TServerMethods1.postCustOrderHistAsync(CustomerID: String; callback: TDBXcallback);
  var
    jsonObject: TJSONObject;
    CallbackValue: TJsonValue;
    errors: Integer;
  begin
    errors := postCustOrderHist(CustomerID); //takes time to post, returns num of failed records
    jsonObject := TJSONObject.create;
    jsonObject.AddPair(tjsonpair.create('errors', errors.ToString));
    CallbackValue := callback.Execute(jsonObject);
  end;
  </code></pre>
  
  <p><strong>Client</strong> has a button which calls the server method PostDataAsync with ID param, and also a callback function “ShowNotification” (which uses windows notification center to show Post notification status).</p>
  
  <p>For now, the application works as following: the client calls the server function synchronously, that means the main thread waits for the server function to finish the HTTP post and then runs the callback notification; the client hanging meanwhile.</p>
  
  <pre><code>TDSCallbackWithMethod = class(TDBXCallback)
  private
    FCallbackMethod: TDSCallbackMethod;
  public
    constructor Create(ACallbackMethod: TDSCallbackMethod);
    function Execute(const Args: TJSONValue): TJSONValue; override; //executes FCallbackMethod
  end;
  
  procedure TMainForm.BtnPostOrderHistoryClick(Sender: TObject);
  var
    callback: TDBXCallback;
    ServerMethods1Client: TServerMethods1Client;
  begin
    //Define Callback to show notification
    callback := TDSCallbackWithMethod.Create(
      function(const Args: TJSONValue): TJSONValue
      var
        errors: integer;
      begin
        errors := Args.GetValue&lt;integer&gt;('errors');
  
        if errors = 0 then
          showNotification(StrSentSuccessfully)
        else
          showNotification(StrSendingFailed + '(' + errors.ToString + ' not sent)');
  
        result := TJsonTrue.Create;
      end);
  
    //Call Server Method
    ServerMethods1Client := TServerMethods1Client.Create(DMServerConnection.SQLConnection1.DBXConnection);
    try
      ServerMethods1Client.postCustOrderHistAsync(EditCustomerId.Text, callback)
    finally
      ServerMethods1Client.Free;
    end;
  end;
  </code></pre>
  
  <p><em>How should the design be in order to call the server methods asynchronously, and let the server run the callback when done? Post function should be able to be called several times with the same user or multiple simultaneously.
  Should the thread be on the server side or Client side? If anybody can help with this, I can send a demo of the application using the Northwind Database.</em></p>
  
  <p><em>Note: I have tried running the client function call in a TTask, it works when the user runs the function once at a time. But when the server method is run several times simultaneously, I get a “DBXError…Read error…callback expecting X got Y”. It seems while the client waits for the response callback format from the first request, it gets confused with other tcp protocol packets initiated from the second request. I have tried running ttask at the server side, I get an exception "TOLEDBCommand.Destroy - interfaces not released"</em></p>