XE6 DataSnap 回叫功能实例(服务器、客户端)编程体会 服务器delphi数据DataSnap XE 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 第二篇 回叫信道 DataSnap XE3新增回叫信道功能。技术关键点: (1)TDBXCallback机制; (2)TDServer.BroadcastMessage方法; (3)TDSClientCallbackChanneManager1.RegisterCallback方法; 三、回叫的方式 1、服务器端回叫所有(同一信道)客户端 2、客户端回叫(同一信道)的其它客户端 3、客户端可以注册多个信道 一、服务器端对回叫信道的设置 1、服务器端回叫信道的注册 编程时,将相关的回叫信道字符,确定下来,便于代码中识别调用。 const DEMOChannel='DemoChannel'; 2、服务器端对客户端的回叫 服务器端使用 TDServer组件的BroadcastMessage方法回叫所有注册的客户端。 TDServer组件重载了二个的BroadcastMessage方法 (1)使用二参数function BroadcastMessage(const ChannelName:String; const Msg: TJSONValue; const ArgType:Integer=TDBXCallback.ArgJason):boolean; overload; 第1参数ChannelName指定通道中所有的回叫客户端; 第2参数Meg回传; 功能:通过Meg传递信息给带ChannelNamer指定的全部客户端。 (2)使用三参数function BroadcastMessage(const ChannelName:String; const CallbackID:String; const Msg: TJSONValue; const ArgType:Integer=TDBXCallback.ArgJason):boolean; overload; 第1参数ChannelName指定通道中所有的回叫客户端; 第2参数CallbackID指定客户端的识别码; 第3参数Meg回传; 功能:通过Meg传递信息给带ChannelNamer中,指定的CallbackID客户端。 实例:例如在服务器端的TMemo1.onChange事件中:procedure TSMainFrm.mmMessageChange(Sender: TObject);var vMessage:TJSONString;begin vMessage := TJSONString.Create(mmMessage.Lines.Text); ServerContainer1.DSServer1.BroadcastMessage(DEMOChannel, vMessage);end; 3、服务器端对客户端注册的回叫通道的搜索 (1)搜索注册回叫通道的客户端ID,通过DSServer1.GetAllChannelClientId方法实现,代码如下:procedure TForm1.btnListAllClientIdsClick(Sender: TObject);var aIdList : TList<String>; sId : String;begin aIdList := ServerContainer5.DSServer1.GetAllChannelClientId(DEMOChannel); try for sId in aIdList do lbAllClientIds.Items.Add(sId); finally aIdList.Free; end;end; (2)搜索注册回叫通道客户端的回叫ID ,通过DSServer1.GetAllChannelCallbackId方法实现,代码如下:procedure TForm1.btnListAllCallbackIdsClick(Sender: TObject);var aIdList : TList<String>; sId : String;begin aIdList := ServerContainer5.DSServer1.GetAllChannelCallbackId(DEMOChannel); try for sId in aIdList do lbAllCallbackIds.Items.Add(sId); finally aIdList.Free; end;end; 二、客户端对回叫信道的设置 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方法,就是用于回叫识别。 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; 上述代码均XE6 编译通过:回叫功能的服务器、客户端实例二个例子:(1)服务器与客户端之间的回叫演示(2)服务器与客户端之间,客户端与客户端之间回叫演示。包含学习体会,以及服务器、客户端调试方法,下载地址:http://download.csdn.net/detail/lyhoo163/7385107欢迎批评指正。 XE6编程,DataSnap回叫功能非常有用,代码下载可运行。谢谢。 这些都不是XE6中的新特性啊,和XE3的一样。另外问一下,服务器上能否取得客户端CallbackId、ClientId对应的socket连接。(多个客户端注册CallbackId时可以重复,ClientId不可重复) 可以的演示http://pan.baidu.com/s/1hqmOVgo InitCallback和ProgCallback不需要(无法释放)吗?即使在FormClose中释放它们,退出时也会出现内存错误。难道是DataSnap自动管理的? 如何设置一个编辑框的内容,只允许双击,不可以输入 关于自动语音呼叫系统? 请问关于打印定位的问题 progressbar 如何固定DBGridEh的列? 有哪位可告诉我DELPHI6.0的注册码,最快的立即给分 showmessage() delphi自動關閉程序 fastreport数据库提交的问题 请问各位大侠,谁对语音卡编程过,讲一讲经验?体会? 窗口布局 delphi webservice进行数据库操作
(1)TDBXCallback机制;
(2)TDServer.BroadcastMessage方法;
(3)TDSClientCallbackChanneManager1.RegisterCallback方法;
三、回叫的方式
1、服务器端回叫所有(同一信道)客户端
2、客户端回叫(同一信道)的其它客户端
3、客户端可以注册多个信道 一、服务器端对回叫信道的设置
1、服务器端回叫信道的注册
编程时,将相关的回叫信道字符,确定下来,便于代码中识别调用。
const DEMOChannel='DemoChannel'; 2、服务器端对客户端的回叫
服务器端使用 TDServer组件的BroadcastMessage方法回叫所有注册的客户端。
TDServer组件重载了二个的BroadcastMessage方法
(1)使用二参数
function BroadcastMessage(const ChannelName:String; const Msg: TJSONValue; const ArgType:Integer=TDBXCallback.ArgJason):boolean; overload;
第1参数ChannelName指定通道中所有的回叫客户端;
第2参数Meg回传;
功能:通过Meg传递信息给带ChannelNamer指定的全部客户端。 (2)使用三参数
function BroadcastMessage(const ChannelName:String; const CallbackID:String; const Msg: TJSONValue; const ArgType:Integer=TDBXCallback.ArgJason):boolean; overload;
第1参数ChannelName指定通道中所有的回叫客户端;
第2参数CallbackID指定客户端的识别码;
第3参数Meg回传;
功能:通过Meg传递信息给带ChannelNamer中,指定的CallbackID客户端。 实例:例如在服务器端的TMemo1.onChange事件中:
procedure TSMainFrm.mmMessageChange(Sender: TObject);
var vMessage:TJSONString;
begin
vMessage := TJSONString.Create(mmMessage.Lines.Text);
ServerContainer1.DSServer1.BroadcastMessage(DEMOChannel, vMessage);
end; 3、服务器端对客户端注册的回叫通道的搜索
(1)搜索注册回叫通道的客户端ID,通过DSServer1.GetAllChannelClientId方法实现,代码如下:procedure TForm1.btnListAllClientIdsClick(Sender: TObject);
var
aIdList : TList<String>;
sId : String;
begin
aIdList := ServerContainer5.DSServer1.GetAllChannelClientId(DEMOChannel);
try
for sId in aIdList do
lbAllClientIds.Items.Add(sId);
finally
aIdList.Free;
end;
end; (2)搜索注册回叫通道客户端的回叫ID ,通过DSServer1.GetAllChannelCallbackId方法实现,代码如下:procedure TForm1.btnListAllCallbackIdsClick(Sender: TObject);
var
aIdList : TList<String>;
sId : String;
begin
aIdList := ServerContainer5.DSServer1.GetAllChannelCallbackId(DEMOChannel);
try
for sId in aIdList do
lbAllCallbackIds.Items.Add(sId);
finally
aIdList.Free;
end;
end; 二、客户端对回叫信道的设置
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方法,就是用于回叫识别。
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;
(1)服务器与客户端之间的回叫演示
(2)服务器与客户端之间,客户端与客户端之间回叫演示。
包含学习体会,以及服务器、客户端调试方法,下载地址:
http://download.csdn.net/detail/lyhoo163/7385107
欢迎批评指正。
另外问一下,服务器上能否取得客户端CallbackId、ClientId对应的socket连接。
(多个客户端注册CallbackId时可以重复,ClientId不可重复)
演示
http://pan.baidu.com/s/1hqmOVgo
难道是DataSnap自动管理的?