datasnap的回调广播
感觉中的datasnap千孔百疮,到xe10已经具备冲击成千上万用户并发的能力了。应该放心用于项目实战了。补课研究10.1 datasnap开发手册。
用到的方法:
(1)TDBXCallback机制;
(2)TDServer.BroadcastMessage方法;
(3)TDSClientCallbackChanneManager1.RegisterCallback方法;
一、回叫的方式
1、服务器端回叫所有(同一信道)客户端
2、客户端回叫(同一信道)的其它客户端
3、客户端可以注册多个信道
server:
- 定义信道。定一条通道公路,然后搜索在此通道上跑的的car。得到每个客户ID
const DEMOChannel='DemoChannel';
2.服务器对客户端回调:
procedure TSMainFrm.mmMessageChange(Sender: TObject);
var vMessage:TJSONString;
begin
vMessage := TJSONString.Create(mmMessage.Lines.Text);
ServerContainer1.DSServer1.BroadcastMessage(DEMOChannel, vMessage);
end;
3.对客户端注册通道和回调通道的搜索,由此得到通道中客户端的ID
procedure TForm1.btnListAllClientIdsClick(Sender: TObject);
var
aIdList : TList<String>;
sId : String;
begin
aIdList := ServerContainer5.DSServer1.GetAllChannelClientId(DEMOChannel);{得到该通道中all的客户端ID}
try
for sId in aIdList do
lbAllClientIds.Items.Add(sId);
finally
aIdList.Free;
end;
end;
procedure TForm1.btnListAllCallbackIdsClick(Sender: TObject);
var
aIdList : TList<String>;
sId : String;
begin
aIdList := ServerContainer5.DSServer1.GetAllChannelCallbackId(DEMOChannel);{得到该回调通道中all的客户端ID
try
for sId in aIdList do
lbAllCallbackIds.Items.Add(sId);
finally
aIdList.Free;
end;
end;
Client:
1、客户端注册
客户端注册回叫信道,由TDSClientCallbackChannelManager1.RegisterCallback方法实现;执行语句如下:
TDSClientCallbackChanneManager1.RegisterCallback(Combobox1.Text, TDemoCallback.Create);
现在我们看一看,客户端向服务器端注册回叫信道时,上述代码包含了注册回叫通道的四个要素:
(1)回叫通道ID,TDSClientCallbackChanneManager.ChannelNament属性值;相关字符应与服务器注册的“回叫信道”字符一致。
(2)客户端ID,TDSClientCallbackChanneManager.ManagerID属性值;每个客户端应明确一个唯一的识别码。
(3)回叫ID ,由TDSClientCallbackChanneManager1.RegisterCallback方法的第1个参数;
(4)回叫方法,由TDSClientCallbackChanneManager1.RegisterCallback第2个参数带入,创建TDemoCallback继承的方法,该对象复载Execute方法,就是用于回叫识别。
//首先继承类TDBXCallback
TDemoCallback = class(TDBXCallback)
public
constructor Create;
function Execute(const Arg: TJSONValue): TJSONValue; override;
end;
//TDemoCallback的excute方法。注意线程异步调用
function TDemoCallback.Execute(const Arg: TJSONValue): TJSONValue;
var
sDemoMessage : String;
begin
Result := TJSONTrue.Create; if (Arg is TJSONString) then
begin
sDemoMessage := TJSONString(Arg).Value;
TThread.Synchronize(nil,
procedure
begin
fmMainForm.mmDemoMessage.Lines.Text := sDemoMessage;
end
);
end;
end;
procedure TfmMainForm.btnStartClick(Sender: TObject);
begin
SetupTask;
EnableDisableButtons(False, True);
DemoChannelManager.RegisterCallback(callbackId, DemoCallback.Create);//注册通道
end; procedure TfmMainForm.btnStopClick(Sender: TObject);
begin
EnableDisableButtons(True ,False);
DemoChannelManager.UnregisterCallback(callbackId);//注销
end;
procedure TForm17.mmMessageChange(Sender: TObject);//服务器通过回调发送信息到该通道all客户端
var
vMessage : TJSONString;
begin
vMessage := TJSONString.Create(mmMessage.Lines.Text);
ServerContainer5.DSServer1.BroadcastMessage(DEMOChannel, vMessage);//发送信息到该通道DEMOChannel中all的客户端
end;
2、客户端与客户端之间的回叫,使用TDSAdminClient类别的NotifyCallback方法
XE在DSProxy单元,增加TDSAdminClient类别,强化回叫功能。其中TDSAdminClient类别的NotifyCallback方法用于客户端之间的回叫,可以回叫指定回叫通道中的特定客户端(客户端ID)或回叫识别(回叫ID)的客户端。声明如下:
function NotifyCallback(ChannelName:string; ClientID:string;CallbackID:string;Msg:TJSONValue; out Respones :TJSONValue):Boolean;
NotifyCallback方法的参数含意:
(1)ChannelName,回叫通道名称;
(2)ClientID,客户端识别;
(3)CallbackID,回叫识别;
(4)Msg,传递信息;
(5)Respones,被叫客户端的回传信息
procedure TfmMainForm.btnBroadcastToClientClick(Sender: TObject);
var
LClient: TDSAdminClient;
LMessage: TJSONString;
LResponse: TJSONValue;
LConnection: TDBXConnection;
begin
LConnection := scnnCallbackServer.DBXConnection;
LClient := TDSAdminClient.Create(LConnection, False);
try
LMessage := TJSONString.Create(Format('呼叫通道:%s,客户端识别:%s,回叫识别:%s,回叫信息:%s',
[DemoChannelManager.ChannelName, cbClientIds.Text, cbCallbackIds.Text, mmChannelCallbacks.Text]));
try
LClient.NotifyCallback(DemoChannelManager.ChannelName, cbClientIds.Text, cbCallbackIds.Text, LMessage, LResponse);
try
if LResponse <> nil then
edtResponse.Text := Format('客户端响应:%s', [LResponse.ToString])
else
edtResponse.Text := Format('客户端响应:%s', ['nil']);
finally
LResponse.Free;
end;
finally
LMessage.Free;
end;
finally
LClient.Free;
end;
end;
datasnap的回调广播的更多相关文章
- Android系统编程入门系列之广播接收者BroadcastReceiver实现进程间通信
在前边几篇关于Android系统两个重要组件的介绍中,界面Activity负责应用程序与用户的交互,服务Service负责应用程序内部线程间的交互或两个应用程序进程之间的数据交互.看上去这两大组件就能 ...
- 十四、Android学习笔记_Android回调函数触发的几种方式 广播 静态对象
一.通过广播方式: 1.比如登录.假如下面这个方法是外界调用的,那么怎样在LoginActivity里面执行登录操作,成功之后在回调listener接口呢?如果是平常的类,可以通过构造函数将监听类对象 ...
- Android中的广播基本实现及回调方法的理解
在Android中broadcast这一节的内容其实不算多主要是牵扯到一个broadcastreceiver类,这个类是一个抽象类,下面有一个抽象方法onreceiver(),可以再我们收到网络状态变 ...
- app微信支付宝支付后台的插件模式+回调通过spring广播处理后续业务(已亲测可用)
写在前面的话:每当我们做一个项目,基本上都会涉及到支付的业务,最常用的莫过于微信和支付宝的支付了,项目有bug,有问题,都不叫问题,可一旦钱出了问题,那就是大问题了,所以在支付业务上我们必须慎之又慎! ...
- Remoting异步回调,向在线用户广播消息
本文目的:向Remoting在线客户端广播消息. 使用的主要技术:异步,回调,广播. 实现过程: 定义远程实例 using System; using System.Collections.Gener ...
- Android学习笔记_74_Android回调函数触发的几种方式 广播 静态对象
一.通过广播方式: 1.比如登录.假如下面这个方法是外界调用的,那么怎样在LoginActivity里面执行登录操作,成功之后在回调listener接口呢?如果是平常的类,可以通过构造函数将监听类对象 ...
- datasnap的初步
datasnap的初步-回调函数 服务器端 TServerMethods1 =class(TComponent) private { Private declarations } public { P ...
- Xamarin.Android广播接收器与绑定服务
一.前言 学习了前面的活动与服务后,你会发现服务对于活动而言似乎就是透明的,相反活动对于服务也是透明的,所以我们还需要一中机制能够将服务和活动之间架起一座桥梁,通过本节的学习,你将会学到广播与绑定服务 ...
- 2、利用蓝牙定位及姿态识别实现一个智能篮球场套件(二)——CC2540/CC2541基于广播的RSSI获得
CC2541一拖多例程中RSSI获得是通过一个事件回调函数实现的,前提是需要连接上蓝牙设备. 这个对于多点定位来说是不可行的,由于主机搜索蓝牙设备过程中也能获得当前蓝牙设备的RSSI等信息,因此可基于 ...
- 【java回调】java两个类之间的回调函数传递
背景交代:熟悉用js开发的cordovaAPP:对java一窍不通的我,老师让做一个监测用户拍照事件的功能,无奈没有找到现成的库,无奈自己动手开发java插件~~0基础java GreenHand,祝 ...
随机推荐
- Eval-Expression.NET:动态执行C#脚本,类似Javascript的Eval函数功能
我们都知道在JavaScript中,我们可以通过Eval来执行JavaScript字符串代码. 下面推荐一个.Net版本的Eval的开源项目. 01 项目简介 Eval-Expression.NET是 ...
- DevOps 企业级 CI/CD 实战 —— 整合 GitLab+Jenkins+Harbor+Docker 实现代码全自动化流程管理
前言 随着 AI 人工智能.云计算.Docker.K8S 等容器技术等的发展,DevOps 得到了广泛的应用和推广,CI / CD ( 持续集成 / 持续部署 )等概念不断深化和完善.CI/CD 是现 ...
- tomcat常用配置详解和优化方法-copy
tomcat常用配置详解和优化方法 参考: http://blog.csdn.net/zj52hm/article/details/51980194 http://blog.csdn.net/wuli ...
- VueRouter案列
案列内容,包含,模板,路由传参,路由重定向,路由嵌套,能够复习路由基本使用,成果如图: 完整代码: 1 <!DOCTYPE html> 2 <html lang="en&q ...
- 《SpringBoot》史上最全SpringBoot相关注解介绍
@SpringBootApplication @SpringBootApplication看作是 @Configuration.@EnableAutoConfiguration.@ComponentS ...
- ORACLE存储过程编程应用实例-门诊药房发药
最近两个整理了门诊药房发药的业务逻辑,准备通过存储过程实现数据处理.耗费两天时间验证终于完成,对存储过程的了解又深入了一些,总结如下: 1.游标的遍历使用了FOR IN语句进行循环,比FETCH与方便 ...
- Dart中操作符详细介绍和使用
dart中静态成员 1 使用satic关键字 来实现类级别的变量和函数 2 静态方法不能够访问非静态成员, 非静态方法可以访问静态成员 3 静态属性,不要通过this去访问 因为this指向的是这个实 ...
- Ubuntu Linux部署DeepSeek
技术背景 DeepSeek是这段时间最热门的话题之一,其蒸馏模型可以实现低成本而高质量的推理,使得我们现在可以在本地小型化的硬件上也用上大模型这一AI利器.本文主要介绍通过Ollama来部署DeepS ...
- DeepSeek太火,但老板们别慌,这里有份AI项目开展手册
关注公众号回复1 获取一线.总监.高管<管理秘籍> 这两天有老板陆续在咨询:到底应该如何基于DeepSeek开展AI项目? 抛开一些偏细节.偏敏感的付费内容,其实有一套方法论倒是可以分享. ...
- Windows中使用http-server搭建一个本地服务
我们在开发中,经常会需要搭建一个本地服务去浏览开发的静态html文件,如果当静态文件中存在一些http.https或者访问文件之类的请求时,直接双击打开html文件是会报错预览不成功的,这时候就需要将 ...