回叫通道
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;