DataSnap 的回叫Word格式.docx
《DataSnap 的回叫Word格式.docx》由会员分享,可在线阅读,更多相关《DataSnap 的回叫Word格式.docx(9页珍藏版)》请在冰豆网上搜索。
3)TDBXCallBack是个虚函数,需用户重新产生一个子类并实现它的Execute的方法。
服务端或客户端在通信时会把这个子类当做参数进行传递。
以下为开发实例的载图及其代码:
(最上面的窗体为服务端,右边的为客户端在虚拟机中,左下边的为本机的客户端)以下为开发大体步骤:
1.开发服务端菜单"
File-New-Other-DataSnapServer"
建立服务端程序,主要在主窗体上放上以下几个控件:
两个listbox,主要获取客户端所有的回叫标识和客户端标识,两上TRadioButton用于发送信息时确认是给同一通道的客户发信息还是给指定的回叫标识发信息,这里主要用到了TJSONValue以下为服务端主界面的源码unitUFrmServer;
interfaceusesWinapi.Windows,Winapi.Messages,System.SysUtils,System.Variants,
System.Classes,Vcl.Graphics,Vcl.Controls,Vcl.Forms,Vcl.Dialogs,
Vcl.StdCtrls;
type
TForm1=class(TForm)
GroupBox2:
TGroupBox;
lbCallBackID:
TListBox;
btnAllCallBackID:
TButton;
edtMessage:
TEdit;
btnSend:
rbAll:
TRadioButton;
rbSingle:
GroupBox1:
btnAllClientID:
lbClientID:
procedurebtnAllCallBackIDClick(Sender:
TObject);
procedurebtnAllClientIDClick(Sender:
procedurebtnSendClick(Sender:
procedureFormCloseQuery(Sender:
TObject;
varCanClose:
Boolean);
private
{Privatedeclarations}
public
{Publicdeclarations}
end;
var
Form1:
TForm1;
implementation
usesServerContainerUnit1,System.Generics.Collections,Data.DBXJSON;
{$R*.dfm}constchannel='
test'
procedureTForm1.btnAllCallBackIDClick(Sender:
//获取所有通道的回叫标识
ls:
TList&
lt;
string&
gt;
ea:
.TEnumerator;
begin
lbCallBackID.Clear;
=ServerContainerUnit1.ServerContainer1.DSServer1.GetAllChannelCallbackId(channel);
=ls.GetEnumerator;
whileea.MoveNextdo
lbCallBackID.Items.Add(ea.Current);
ls.Free;
end;
procedureTForm1.btnAllClientIDClick(Sender:
//获取所有通道的客户端标识
lbClientID.Clear;
=ServerContainerUnit1.ServerContainer1.DSServer1.GetAllChannelClientId(channel);
lbClientID.Items.Add(ea.Current);
procedureTForm1.btnSendClick(Sender:
//发送信息
js:
TJsonString;
callid:
string;
=TJSONString.Create(edtMessage.Text);
ifrbAll.Checkedthen
ServerContainer1.DSServer1.BroadcastMessage(channel,js)
else
begin
=lbCallBackID.Items.Strings[lbCallBackID.ItemIndex];
ifcallid&
&
'
then
ServerContainerUnit1.ServerContainer1.DSServer1.BroadcastMessage(channel,callid,js);
procedureTForm1.FormCloseQuery(Sender:
ifMessageDlg('
你要关闭服务吗?
mtInformation,[mbYes,mbNo],0,mbno)=idnothen
CanClose:
=False
ifServerContainerUnit1.ServerContainer1.DSServer1.Startedthen
ServerContainerUnit1.ServerContainer1.DSServer1.Stop;
=True;
end.2.开发客户端建立应用程序并在菜单"
File-New-DataSnapServer"
选择DataSnapClientModule选项,连接上面建立的服务程序并自动产生服务端的导出函数单元及DataModule类,在DataModule类上放TDSClientCallbackChannelManager控件,它主要用于向服务端注册回叫标识,另它的ManagerID是用于客户端的标识,千万不要忘记它的相关属性设置,否则其它电脑上的客户端是无法访问服务端的。
在客户端主界面上放以下控件:
TMemo:
用于显示收到的信息两个Combobox,让用户输入其它客户端的回叫ID和客户端标识ID,用于给其它客户端发信息一个Tedit,用于写入要发送的信息内容,一个button用于发送动作两个TEdit,主要是让程序在运行时让用户输入客户端标识ID和客户端回叫ID。
一个Tbutton用于手动注册回叫事件另加上一个TEdit,主要设置服务端的地址以下为客户端主界面源码:
unitUMain;
interfaceuses
Winapi.Windows,Winapi.Messages,System.SysUtils,System.Variants,System.Classes,Vcl.Graphics,
Vcl.Controls,Vcl.Forms,Vcl.Dialogs,Data.DBXJSON,Vcl.StdCtrls,Vcl.ComCtrls;
TFrmClient=class(TForm)
mmReceive:
TMemo;
StatusBar1:
TStatusBar;
edtCallBack:
Label1:
TLabel;
Button1:
Label2:
edtServer:
edtSend:
Label3:
Label4:
cbCallBack:
TComboBox;
cbClientID:
label5:
edtClientID:
procedureButton1Click(Sender:
procedureFormClose(Sender:
varAction:
TCloseAction);
procedureFormCreate(Sender:
procedureRegisterCallBackID;
functionConnectServer:
Boolean;
procedureAddCombobox(constClientID,CallID:
string);
procedureSendMsgToOtherClient;
TDataSnapCallBack=class(TDBXCallback)
{privatedeclarations}
protected
{protecteddeclarations}
{publicdeclarations}functionExecute(constArg:
override;
published
{publisheddeclarations}
FrmClient:
TFrmClient;
const
channel='
usesClientModuleUnit1,Data.SqlExpr,Data.DBXCommon,Datasnap.DSProxy;
{$R*.dfm}functionTFrmClient.ConnectServer:
Result:
=false;
withClientModule1.SQLConnection1do
Params.Clear;
withConnectionData.Propertiesdo
Values[TDBXPropertyNames.DriverName]:
='
DataSnap'
Values[TDBXPropertyNames.CommunicationProtocol]:
tcp/ip'
Values[TDBXPropertyNames.HostName]:
=edtServer.Text;
Values[TDBXPropertyNames.Port]:
211'
Values[TDBXPropertyNames.BufferKBSize]:
32'
Values[TDBXPropertyNames.DatasnapContext]:
datasnap/'
LoginPrompt:
=False;
try
ClientModule1.SQLConnection1.Open;
=ClientModule1.SQLConnection1.ConnectionState=csStateOpen;
ClientModuleUnit1.ClientModule1.DSClientCallbackChannelManager1.DSHostname:
//一定要设置
exceptend;
procedureTFrmClient.FormCreate(Sender:
beginend;
{TDataSnapCallBack}functionTDataSnapCallBack.Execute(constArg:
str:
=TJSONString.Create('
成功回叫客户端'
);
//一定要回传给服务端信息,在客户端发送时会显示
ifAssigned(Arg)then
if(ArgisTJSONString)then
=TJSONString(Arg).Value;
TThread.Synchronize(nil,
procedure//匿名方法
FrmClient.mmReceive.Lines.Add(str);
end
);
procedureTFrmClient.AddCombobox(constClientID,CallID:
ifcbClientID.Items.IndexOf(clientID)=-1then
cbClientID.Items.Add(ClientID);
ifcbCallBack.Items.IndexOf(CallID)=-1then
cbCallBack.Items.Add(CallID);
procedureTFrmClient.btnSendClick(Sender:
SendMsgToOtherClient;
procedureTFrmClient.Button1Click(Sender:
if(edtCallBack.Text='
)or(edtClientID.Text='
)then
ShowMessage('
请输入相关标识.'
exit;
RegisterCallBackID;
procedureTFrmClient.FormClose(Sender:
ifClientModuleUnit1.ClientModule1.SQLConnection1.ConnectionState=csStateOpenthen
ClientModule1.DSClientCallbackChannelManager1.UnregisterCallback(callid);
ClientModule1.SQLConnection1.Close;
procedureTFrmClient.RegisterCallBackID;
i:
Integer;
//callid:
=DateTimeToStr(now);
AddCombobox(edtClientID.Text,edtCallBack.Text);
=edtCallBack.Text;
ClientModule1.DSClientCallbackChannelManager1.ManagerId:
=edtClientID.Text;
ifConnectServerthen
StatusBar1.Panels[0].Text:
已成功连接服务器'
ifClientModule1.DSClientCallbackChannelManager1.RegisterCallback(callid,TDataSnapCallBack.Create)then
StatusBar1.Panels[1].Text:
已成功注册,CallID:
+Callid
注册CallID失败.'
endelse
连接服务器失败'
=cbCallBack.Items.IndexOf(callid);
cbCallBack.Items.Delete(i);
//删除注册失败的id
procedureTFrmClient.SendMsgToOtherClient;
AC:
TDSAdminClient;
//发送消息管理类
vMessage:
TJSONString;
outMessage:
TJSONValue;
clientID,CallbackID,sMessage:
clientID:
=cbClientID.Text;
CallbackID:
=cbCallBack.Text;
=TDSAdminClient.Create(ClientModule1.SQLConnection1.DBXConnection,False);
sMessage:
=Format('
呼叫通道:
%s,回叫识别:
%s,客户端标识:
%s,发送信息:
%s'
[channel,callbackid,clientid,edtSend.Text]);
=TJSONString.Create(sMessage);
AC.NotifyCallback(channel,clientID,CallbackID,vMessage,outMessage);
ifAssigned(outMessage)then
mmReceive.Lines.Add(Format('
返回信息:
[outmessage.ToString]))
mmReceive.Lines.Add('
对方没有回应'
);
finally
outMessage.Free;
vMessage.Free;
AC.Free;
end.