【问题标题】:Delphi datasnap callback - BroadCast questionDelphi datasnap 回调 - 广播问题
【发布时间】:2011-05-07 22:25:09
【问题描述】:

我又一次陷入了这样一种情况,即我花费了大量的时间来尝试根据自己的需要自定义 datasnap 回调示例。 我是老派 OOP 程序员,在我的“工具箱”PODO 样式中有几个非常大的对象层次结构 :-) .. 拥有这个出色的数据快照功能,我想利用回调的力量。

但是 - 当我实现它时......它只是失败了......(FASTMM4 报告内存泄漏)。

尝试创建一个简单的 VCL 数据快照服务器 - 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 吗?

问候 比亚恩

【问题讨论】:

  • @Bimmer_R- 建议:请向我们解释它是如何失败的 - 会发生什么?德尔福提出了什么例外?你得到什么错误信息?我认为您不会通过简单地告诉我们“它根本失败”并要求我们去构建一个数据快照服务器并找出发生了什么或没有发生什么来得到很多答案。
  • @Mikey ...对不起..我当然应该提供所有需要的信息。当我说失败时-这意味着违反访问权限..或者正如我指出的那样。 Fastmm4 报告内存泄漏。创建数据快照服务器应用程序。你实际上只需要很少的步骤/点击,它几乎和启动一个新的 vcl 表单应用程序一样快:-) 这是一个很好的例子,说明如何设置一个 datasnap 服务器 - 并使用回调。 edn.embarcadero.com/article/41374 我看到的唯一区别是,我是从服务器广播的……但这真的不应该是一个问题……或者是吗?

标签: delphi callback datasnap podo


【解决方案1】:

您提供给通知或广播调用的对象随后归该调用所有。因此不要调用“AObject.Free;”或“aJSONVal.Free;”。这样做通常会导致访问冲突或其他与内存管理相关的问题。

另请注意,广播消息会被放入服务器上的队列中,然后在不同的线程中发送。这意味着,当您对 Broadcast 的调用返回时,它实际上还没有将消息发送给所有客户端。

希望对你有帮助

垫子

【讨论】:

  • 嗨,垫子。感谢您对此感兴趣。我已经修改了 CallbackChannels 演示程序 - 并将其放在 megaupload 上(不知道如何通过 SO 共享文件 - 如果可能的话)。 megaupload.com/?d=BL0SZC98 记住 - 对回调 ID 进行回调广播......仍然无法正常工作。但是广播到频道是可以的。并且回调id/clientid 的notifyobject 也可以。我希望你觉得这个演示很有用。
【解决方案2】:

可能的答案:您的问题含糊不清,但根据您所说的,我将从这里开始:

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

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

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

您正在使用需要 3 个参数的第二个重载 - 您的回调标识符设置正确吗?

【讨论】:

  • 嗨,米奇。你是对的 - 每个广播方法都有两个重载。但是当我阅读“说明”时......广播不需要任何“设置”。您可以随时随地播放任何内容。如果没人听,那就无所谓了。并且有 4 个可能的广播 - 我只能让一个工作。所有其他人都因访问冲突或内存泄漏而失败。
  • @Bimmer_R:我不会将内存泄漏本身称为故障。但是 AV 是在客户端还是在服务器端生成的?您的部署是如何设置的?您是否在远程机器上或所有本地机器上都有客户端?你能追踪整个执行路径直到 AV 吗?你用的是什么版本的德尔福?您是否在 IDE 中打开了“打破 Delphi 语言期望”?我相信您知道,AV 通常会掩盖真正的问题。如果在远程客户端上生成异常,它可能会作为来自服务器调用的 AV 出现,它掩盖了实际的客户端异常。请 - 细节! HTH
  • @Bimmer_R - 我认为当你说“它只是失败”时,你的意思是有时什么都没有发生,除了你看到报告的泄漏,对吗? “我只能让一个工作。所有其他人都因访问冲突或内存泄漏而失败” - 工作的有什么不同?这可能会引导您找到答案。
  • @Mikey。再次嗨 - 我现在有一些工作。我想分享我的知识。对频道(所有回调/客户端)执行 BroadCastObject 非常容易。 NotifyObject(特定通道、回调、客户端)显然也是如此。我失败的地方是特定回调的广播对象。由于某种原因,它不会工作。我已经修改了 embacadero CallBackChannels 演示程序并将其邮寄给 Pawel Glowacki,我刚刚与他一起参加了关于该领域的为期 2 天的研讨会。如果有人想获得 ChannelCallbackDemo 的修改版本,请告诉我。
  • @Bimmer_R - 感谢您的接受 - 我没有真正回答任何问题,但我想我的方向是正确的?现在,这个修改后的版本可以满足您的需要吗?如果是这样,我希望看到它 - 现在不使用此功能,但它非常强大,并且想知道如何在必要时正确使用它。 Tnx
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-06-29
  • 2016-12-11
  • 2021-05-01
  • 2012-09-03
  • 1970-01-01
  • 2011-02-22
  • 1970-01-01
相关资源
最近更新 更多