Delphi DataSnap回调 - 广播问题

3
我又一次陷入了这样一种情况,我已经花费了大量的时间来尝试根据我的需求自定义datasnap回调示例。 我是一名老派的面向对象编程员,我的“工具箱”中有几个非常庞大的对象层次结构,采用PODO风格:-),由于拥有这个伟大的datasnap特性,我想利用回调功能的力量。
但是-当我实现它时……它就会失败…(FASTMM4报告内存泄漏)。
请尝试创建一个简单的VCL datasnap服务器-TCP。 然后添加一个按钮和这个源代码...
procedure TForm1.Button1Click(Sender: TObject);
var
//  AObject : TObject;
  aJSONVal : TJSONValue;
begin
//  AObject := TObject.Create;
//  ServerContainer1.DSServer1.BroadcastObject('SomeChannel','SomeCallbackID', AObject);
//  AObject.Free;

  aJSONVal := TJSONObject.Create;
  ServerContainer1.DSServer1.BroadcastMessage('SomeChannel','SomeCallbackID',aJSONVal);
  // aJSONVal.Free; // Mat pointed out that this is done by the broadcast.
end;

只要您继续使用TJSONValue,它就可以正常工作...但是尝试切换注释的代码-您就会明白我的意思。
我当然可以将所有现有代码更改为JSON...但这显然是不可接受的。
是否有人知道如何使用BroadcastOBJECT或NotifyOBJECT?
问候 Bjarne

@Bimmer_R- 建议:请向我们解释它是如何失败的 - 发生了什么?Delphi引发了什么异常?你得到了什么错误信息?我认为,仅仅告诉我们“它只是失败了”,并要求我们构建一个datasnap服务器来找出发生了什么或没有发生什么,你不会得到太多答案。 - Vector
@Mikey...抱歉...当然我应该提供所有所需的信息。当我说失败时,它意味着访问违规...或者正如我指出的那样,Fastmm4报告了内存泄漏。要创建一个数据快照服务器应用程序,您实际上只需要很少的步骤/点击,几乎与启动新的VCL表单应用程序一样快:-)这是设置datasnap服务器并使用回调的绝佳示例。http://edn.embarcadero.com/article/41374 我看到的唯一区别是我正在从服务器广播...但这真的不应该成为问题...难道不是吗? - Bimmer_R
2个回答

2
您给Notify或Broadcast调用的对象将由该调用拥有。因此,请勿调用"AObject.Free;"或"aJSONVal.Free;"。这样做通常会导致访问冲突或其他与内存管理相关的问题。
另请注意,广播消息会被放入服务器的队列中,并在不同的线程中稍后发送。这意味着,当您调用Broadcast时返回,它实际上还没有将消息发送给所有客户端。
希望能对您有所帮助,
Mat

嗨Mat。 感谢您对此的关注。我已经修改了CallbackChannels演示程序,并将其放在megaupload上(不知道如何通过SO共享文件-如果可能的话)。http://www.megaupload.com/?d=BL0SZC98请记住-向回调ID进行回调广播...仍然无法工作。但是,向通道进行广播是可以的。并且向回调ID /客户端ID发送notifyobject也可以。希望您会发现这个演示很有用。 - Bimmer_R

0

可能的答案:你的问题比较模糊,但根据你所说的,我会从这里开始:

Delphi XE 帮助文档:(ms-help://embarcadero.rs_xe/vcl/DSServer.TDSServer.BroadcastObject.html):

function BroadcastObject(const ChannelName: String; const CallbackId: String; const Msg: TObject): boolean; overload;

第二个重载函数将一个对象发送给所有具有给定注册回调标识符的客户端回调。为此,需要在调用中提供一个额外的 CallbackId 参数。

你正在使用三个参数的第二个重载函数 - 你的回调标识符设置正确了吗?


嗨,Mikey。 你是正确的 - 每个广播方法都有两个重载。但是根据我阅读的“说明”..广播不需要任何“设置”。您可以随时广播任何内容。如果没有人听,那就没关系了。 而且有4个可能的广播 - 我只能让其中一个工作。 其他所有广播都会失败,出现访问冲突或内存泄漏。 - Bimmer_R
@Bimmer_R - 我了解你所说的“它只是失败”意味着有时候什么都不会发生,除了你看到一个泄漏报告,对吗?“我只能让其中一个工作。其他所有的都会出现访问冲突或内存泄漏”的问题在于哪一个与其它不同?这可能会帮助你找到答案。 - Vector
@Mikey。你好,我现在有一些东西可以工作了。我想分享我的知识。向通道(所有回调/客户端)进行BroadCastObject非常容易。显然,NotifyObject(特定通道、回调、客户端)也很容易。我失败的地方是将BroadCastObject发送到特定的回调函数。出于某种原因它不起作用。我修改了embacadero CallBackChannels演示程序,并将其发送给Pawel Glowacki,我刚刚参加了他在这个领域的为期两天的研讨会。如果有人想要获取ChannelCallbackDemo的修改版本,请告诉我。 - Bimmer_R
@Bimmer_R - 你参加的这个工作坊是在哪里举办的?是Embacadero计划的一部分吗?是线上还是面对面的工作坊?谢谢。 - Vector
是的,你很幸运 - Delphi在欧洲比美国(我所在的地方)更强大 - 开发者日没有来纽约!微软在这里如此占主导地位 - 美国一直更加偏爱C语言 - 欧洲有深厚的Pascal根基。请发送您编写的内容 - 不确定您在SO上如何操作... - Vector
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接