/ / Грешка в претоварен метод на изпълнение на TDBXCallback, който приема и връща TObject - delphi, callback, datasnap

Bug в претоварен метод за изпълнение на TDBXCallback, който приема и връща TObject - delphi, callback, datasnap

Има претоварена версия на функцията Execute на TDBXCallback обаждания в Data.DBXJSon, която изглежда така

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;

Това следва от пример във видеото, представено от Мат ДеЛонг

Обратни повиквания в тежко тегло с DataSnap - Част 1: Дебел клиент

Обратното извикване работи перфектно, но само точноведнъж! При второто обаждане от сървъра (Button2Click) получавам AV в клиента. Възможно е грешка в DBX кода. Не знам. Не мога да проследя там. Или може би съм инициализирал резултата от ServerChannelCallBack.Execute неправилно. Всяка помощ се оценява.

UPDATE

Обратното обаждане се регистрира на клиента така:

        TFormClient = class(TForm)
CMServerChannel: TDSClientCallbackChannelManager;
...
private
ServerChannelCBID: string;
...
procedure TFormClient.FormCreate(Sender: TObject);
begin
ServerChannelCBID := DateTimeToStr(now);
CMServerChannel.RegisterCallback(
ServerChannelCBID,
ServerChannelCallback.Create
);
...

Отговори:

2 за отговор № 1

Основавам този отговор на проектите на DataSnap Server + Client, които могат да бъдат изтеглени от Delphi Seattle с помощта на „File | Open от контрола на версиите“

https://radstudiodemos.svn.sourceforge.net/svnroot/radstudiodemos/branches/RadStudio_XE/Delphi/DataSnap/CallbackChannels

това е споменато тук: 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 сървърът и клиентът работят добре и мога да щракна върху бутона на сървъра толкова пъти, колкото ми харесва и нито сървърът, нито някой от клиентите не се „забиват“. Затова смятам, че проблемът ви трябва да е специфичен за нещо в кода, който използвате, но поне свързаният проект ви дава нещо, от което можете да работите и да сравните.

Btw, промених TCallbackClient.Execute вид на връщане към TJSONTrue.Create (същото като другото отмяна), защото това е каквов „Наръчника за Delphi 2010“ на Марко Канту пише, че трябва да се върне, разбира се, в контекста на „лек“ обратен разговор, докато ServerMethod се изпълнява: връщането на TJSONFalse казва на сървъра да отмени изпълняващия ServerMethod. еднакво добре с TObject.Create ти използва.