2011年10月3日星期一

datasnap的初步-回调函数

服务器端
 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









没有评论:

发表评论