我正在编写一个Datasnap应用程序,在客户端/服务器之间使用TCP连接,服务器连接到SQL server。
服务器
具有具有所有数据集查询和SQL连接的datamodule DM1。DM1还具有REST请求/客户端/响应组件。
DM1有一个公开的函数PostDataAsync,ID为param:从数据集生成json,然后通过HTTP将其发布到RESTFul服务。它返回未能在回调参数中发布的记录数。
此DM1的DSServer是调用。
调用服务器类型应确保每个服务器方法调用都有自己的数据库连接、数据集、Rest组件,这些组件不会有多个调用干扰彼此的数据(如果添加了并行线程)。
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;
客户
有一个按钮,该按钮使用ID param调用服务器方法PostDataAsync,还有一个回调函数ShowNotification(它使用windows通知中心显示通知后状态)。
目前,应用程序的工作方式如下:客户端同步调用服务器函数,这意味着主线程等待服务器函数完成HTTP post,然后运行回调通知;客户同时被绞死。
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<integer>('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;
注意:我已经尝试在TTask中运行客户机函数调用,当用户一次运行一次函数时,它就会工作。但是当服务器方法同时运行多次时,我得到一个DBXErrorRead errorcallback,期望X得到Y。当客户端等待来自第一个请求的响应回调格式时,它似乎与来自第二个请求的其他tcp协议包混淆了。我曾尝试在服务器端运行ttask,但出现异常“TOLEDBCommand.Destroy-接口未发布”