在Data.DBXJSon中有一个TDBXCallback调用的Execute函数的重载版本,看起来像这样
function Execute(Arg: TObject): TObject; overload; virtual; abstract;
在我的Datasnap客户端中,我实现了这样:
type
ServerChannelCallBack = class(TDBXCallback)
public
function Execute(const Arg: TJSONValue): TJSONValue; overload; override; // this works!
function Execute(Arg: TObject): TObject; overload; override; // this doesn't
end;
function ServerChannelCallBack.Execute(Arg: TObject): TObject;
var
i: Integer;
begin
Result := TObject.Create; // is this correct?
try
if Arg is TStringList then
begin
FormClient.QueueLogMsg('ServerChannel', 'Got TStringList');
for i := 0 to TStrings(Arg).Count - 1 do
FormClient.QueueLogMsg('ServerChannel', TStringList(Arg)[i]);
end;
finally
end;
end;
这是从Datasnap服务器调用的,如下所示:
procedure TFormServer.Button2Click(Sender: TObject);
var
sr: TStringList;
begin
sr := TStringList.Create;
try
sr.Add('one');
sr.Add('two');
ServerContainer2.DSServer1.BroadcastObject('SERVERCHANNEL', sr);
finally
// sr
end;
end;
以下是Matt DeLong提供的视频中的一个例子
Heavyweight Callbacks with DataSnap - Part 1: Thick Client
回调效果很好,但只有一次!在服务器的第二次调用(Button2Click)上,我在客户端获得了一个AV。它可能是DBX代码中的错误。我不知道。我无法在那里追踪。或者我可能错误地从ServerChannelCallBack.Execute初始化了Result。任何帮助表示赞赏。
更新
回调在客户端上注册如下:
TFormClient = class(TForm)
CMServerChannel: TDSClientCallbackChannelManager;
...
private
ServerChannelCBID: string;
...
procedure TFormClient.FormCreate(Sender: TObject);
begin
ServerChannelCBID := DateTimeToStr(now);
CMServerChannel.RegisterCallback(
ServerChannelCBID,
ServerChannelCallback.Create
);
...
答案 0 :(得分:2)
我的答案基于DataSnap Server + Client项目,可以使用`File |从Delphi Seattle内部下载。从版本控制中打开'
这里提到的是:http://edn.embarcadero.com/article/41374。
服务器和客户端中的表单都需要稍微更正才能使它们编译,命名为将JSon
添加到其使用列表中。
在服务器表单上,我添加了以下内容:
procedure TForm3.Button1Click(Sender: TObject);
var
sr: TStringList;
begin
Inc(CallbackCount); // A form variable
sr := TStringList.Create;
try
sr.Add('Callback: ' + IntToStr(CallbackCount));
sr.Add('two');
ServerContainer1.DSServer1.BroadcastObject('ChannelOne', sr);
finally
// No need for sr.free
end;
end;
(我使用ChannelOne与客户保持一致)
在客户端我有:
function TCallbackClient.Execute(Arg: TObject): TObject;
var
i: Integer;
begin
// Result := TObject.Create; // is this correct?
Result := TJSONTrue.Create;
try
if Arg is TStringList then
begin
QueueLogValue('Server: Got TStringList');
for i := 0 to TStrings(Arg).Count - 1 do
QueueLogValue('Server:' + TStringList(Arg)[i]);
end;
finally
end;
end;
根据您在q中显示的代码的变化,服务器和客户端运行正常,我可以根据需要多次单击服务器按钮,服务器和任何客户端都无法获得& #34;卡住&#34 ;.因此,我认为您的问题必须特定于您正在使用的代码中的某些内容,但至少链接的项目会为您提供一些工作方式并与之进行比较。
顺便说一句,我将TCallbackClient.Execute
返回类型更改为TJSONTrue.Create
(与其他覆盖相同),因为它在Marco Cantu的Delphi 2010手册中所说的应该是无可否认地回归"轻量级" ServerMethod执行时回调:返回TJSONFalse告诉服务器取消正在执行的ServerMethod。但是,来自服务器的回调与您使用的TObject.Create
同样有效。