TServerMethods1 = class(TComponent)
private
{ Private declarations }
public
{ Public declarations }
function Test(funcCallBack: TDBXCallback): boolean;
end;
function TServerMethods1.Test(funcCallBack: TDBXCallback): boolean;
begin
funcCallBack.Execute(TJSONNumber.Create(20)).Free;
sleep(1000);
Result := True;
end;
客户端,这个必须继承自TDBXCallback
TFuncCallback = class(TDBXCallback)
function Execute(const Arg: TJSONValue): TJSONValue; override;
end;
function TFuncCallback .Execute(const Arg: TJSONValue): TJSONValue;
var
i: Integer;
begin
i := TJSONNumber(Arg).AsInt;//可以的到服务器回调来的参数
Result := TJSONNull.Create;
end;
procedure TForm2.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
没有评论:
发表评论