云题海 - 专业文章范例文档资料分享平台

当前位置:首页 > datasnap的初步

datasnap的初步

  • 62 次阅读
  • 3 次下载
  • 2025/5/1 15:02:44

datasnap的初步-回调函数

服务器端 TServerMethods1 =class(TComponent) private { Private declarations } public { Public declarations } functionTest(funcCallBack: TDBXCallback):boolean; end; functionTServerMethods1.Test(funcCallBack: TDBXCallback):boolean; begin funcCallBack.Execute(TJSONNumber.Create(20)).Free; sleep(1000); Result :=True; end; 客户端,这个必须继承自TDBXCallback TFuncCallback =class(TDBXCallback) functionExecute(constArg: TJSONValue): TJSONValue;override; end; functionTFuncCallback .Execute(constArg: TJSONValue): TJSONValue; var i:Integer; begin i := TJSONNumber(Arg).AsInt;//可以的到服务器回调来的参数 Result := TJSONNull.Create; end; procedureTForm2.Button1Click(Sender: TObject); begin ClientModule1.ServerMethods1Client.Test(funcCallBack); end; initialization funcCallBack:= TFuncCallBack.Create; finalization //FreeAndNil(funcCallBack);

到此,实现了最基本的回叫。

D2010起提供了DSClientCallbackChannelManager这个控件,这是为了实现一次注册,多次回叫,使用方法很简单

1。客户端使用 DSClientCallbackChannelManager注册回叫函数 function RegisterCallback(const CallbackId: String; const Callback: TDBXCallback): boolean; overload; DSClientCallbackChannelManager控件带有一个ChannelName的属性,用于CallbackId分组用。ManagerId属性,可理解为ClientId,ClientId必须是唯一的,相同的ClientId,会被认为是相同地点来的连接。

不明白为啥 DSClientCallbackChannelManager要自己设置连接属性,而不是走TSQLConnection。

2。服务器端是TDSServer来做事,它有 两个函数 function BroadcastMessage(const ChannelName: String; const Msg: TJSONValue; const ArgType: Integer = TDBXCallback.ArgJson): boolean; overload; function BroadcastMessage(const ChannelName: String; const CallbackId: String; const Msg: TJSONValue; const ArgType: Integer = TDBXCallback.ArgJson): boolean; overload; 第一个函数,回调在ChannelName里面所有的callbackid, 第二个是回调ChannelName里面指定的CallBackId

服务器上用GetAllChannelCallbackId能返回在某个ChannelName里面所有的CallbackId。

到此,我们就能使用DSClientCallbackChannelManager来制作一个简单的聊天软件,并能实现私聊的功能。但是如何处理,聊天用户掉线的问题,就比较麻烦了。

和RO比较,这设计有些像RO里的TROEventReceiver,但远没RO灵活, TROEventReceiver直接就能订阅(RegisterEventHandlers)上一堆服务器的事件,DataSnap却要定义一堆的TDBXCallback。

datasnap的初步 TDSClientCallbackChannelManager的工作方式

理解一下TDSClientCallbackChannelManager的工作方式吧

客户端调用RegisterCallback,其实就是开始了一个线程TDSChannelThread,该线程起一个dbxconnection,连接到服务器上,执行DSAdmin.ConnectClientChannel,服务器上的这个DSAdmin.ConnectClientChannel很神奇,所有的数据传输都在这里了,这个连接不会关闭,以做到服务器往客户端push数据。TDSClientCallbackChannelManager只能做到服务器向客户端推送数据,单向的。客户端要向服务器送数据,走TDSAdminClient的NotifyCallback方法,也就是只有经过SQLConnection。

DSAdmin(在Datasnap.DSCommonServer单元)是TDBXServerComponent(在Datasnap.DSPlatform单元)的子类,ConnectClientChannel函数直接call ConsumeAllClientChannel。 代码摘抄 functionTDBXServerComponent.ConsumeAllClientChannel(constChannelName, ChannelId, CallbackId, SecurityToken:String; ChannelNames: TStringList; ChannelCallback: TDBXCallback; Timeout:Cardinal):Boolean; ... begin // wait for exit message repeat //这里开始 Data :=nil; IsBroadcast :=false; ArgType := TDBXCallback.ArgJson; QueueMessage :=nil; TMonitor.Enter(CallbackTunnel.Queue); try {Wait for a queue item to be added if the queue is empty, otherwise don't wait and just pop the next queue item} ifCallbackTunnel.Queue.QueueSize =0then IsAquired := TMonitor.Wait(CallbackTunnel.Queue, Timeout) else IsAquired :=true; ifIsAquiredand(CallbackTunnel.Queue.QueueSize >0)then begin {Get the next queued item from the tunnel} QueueMessage := CallbackTunnel.Queue.PopItem; Data := QueueMessage.Msg; IsBroadcast := QueueMessage.IsBroadcast; ArgType := QueueMessage.ArgType; end; finally TMonitor.Exit(CallbackTunnel.Queue); end; ifIsAquiredand(Data <>nil)then ifIsBroadcastthen begin try Msg := TJSONObject.Create(TJSONPair.Create('broadcast', TJSONArray.Create(Data).Add(ArgType))); if(QueueMessage.ChannelName <> EmptyStr)and (QueueMessage.ChannelName <> CallbackTunnel.ServerChannelName)then Msg.AddPair(TJSONPair.Create('channel', QueueMessage.ChannelName)); try ChannelCallback.Execute(Msg).Free; except try // Remove the callback tunnel from the list, it will be freed at the end of this method InternalRemoveCallbackTunnel(DSServer, CallbackTunnel); except end; raise; end; finally QueueMessage.InstanceOwner :=false; FreeAndNil(QueueMessage); end; end elseifAssigned(QueueMessage)then begin TMonitor.Enter(QueueMessage); try Msg := TJSONObject.Create( TJSONPair.Create('invoke', TJSONArray.Create( TJSONString.Create(QueueMessage.CallbackId), Data).Add(ArgType))); try QueueMessage.Response := ChannelCallback.Execute(Msg); except onE : Exceptiondo begin QueueMessage.IsError :=True; QueueMessage.Response := TJSONObject.Create(TJSONPair.Create('error', E.Message)); ifChannelCallback.ConnectionLostthen begin WasConnectionLost :=True; TMonitor.Pulse(QueueMessage); try // Remove the callback tunnel from the list, it will be freed at the end of this method InternalRemoveCallbackTunnel(DSServer, CallbackTunnel); except end;

搜索更多关于: datasnap的初步 的文档
  • 收藏
  • 违规举报
  • 版权认领
下载文档10.00 元 加入VIP免费下载
推荐下载
本文作者:...

共分享92篇相关文档

文档简介:

datasnap的初步-回调函数 服务器端 TServerMethods1 =class(TComponent) private { Private declarations } public { Public declarations } functionTest(funcCallBack: TDBXCallback):boolean; end; functionTServerMethods1.Test(funcCallBack: TDBXCallback):boolean; begin funcCallBack.Execute(TJSONNumber.Create(20)).Free; sleep(1000); Result :=True; end; 客户端,这个必须继承自TDBXCallback TFuncC

× 游客快捷下载通道(下载后可以自由复制和排版)
单篇付费下载
限时特价:10 元/份 原价:20元
VIP包月下载
特价:29 元/月 原价:99元
低至 0.3 元/份 每月下载150
全站内容免费自由复制
VIP包月下载
特价:29 元/月 原价:99元
低至 0.3 元/份 每月下载150
全站内容免费自由复制
注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信:fanwen365 QQ:370150219
Copyright © 云题海 All Rights Reserved. 苏ICP备16052595号-3 网站地图 客服QQ:370150219 邮箱:370150219@qq.com