難道要獲得客戶端ip嗎 要用兩對服務客戶端
uj5u.com熱心網友回復:
使用套接字~uj5u.com熱心網友回復:
通過XE的服務器與客戶端回叫函式,可以由服務器向幾個客戶端同時發送訊息(字符)。uj5u.com熱心網友回復:
http://bbs.csdn.net/topics/390794253第一篇 服務器與客戶端回叫
從Delphi2010開始,DataSnap支持回叫(Call Back)機制。這樣,在呼叫耗時較長的方法時,通過回叫機制,回傳服務器行程或正在處理的目標物件。
一、客戶端實作步驟
在客戶端宣告TClientModule1的單元檔案uClientModule中:
1、宣告一個從TDBXCallback繼承下來的物件(用于回叫引數值),并實作復載的步驟。
type
TInitCallback = class(TDBXCallback)
function Execute(const Arg: TJSONValue): TJSONValue; override;
end;
TProgCallback = class(TDBXCallback)
function Execute(const Arg: TJSONValue): TJSONValue; override;
end;
2、初始化創建該物件
Initialization // 初始化 創建
InitCallback := TInitCallback.Create;
ProgCallback := TProgCallback.Create;
3、實作宣告的方法
function TProgCallback.Execute(const Arg: TJSONValue): TJSONValue;
begin
with MainFrm do
begin
ProgressBar1.Position := TJSONNumber(Arg).AsInt;
Button5.Enabled := (TJSONNumber(Arg).AsInt = ProgressBar1.Max);
end;
//重繪螢屏
Application.ProcessMessages;
Result := TJSONNull.Create; // 回傳Null值
end;
function TInitCallback.Execute(const Arg: TJSONValue): TJSONValue;
begin
with MainFrm do
begin
ProgressBar1.Max := TJSONNumber(Arg).AsInt;
ProgressBar1.Step := 5;
Edit1.Text := '總時長:' + TJSONNumber(Arg).ToString + '秒';
Button5.Enabled := False;
end;
Result := TJSONNull.Create;
end;
4、呼叫回叫方法
procedure TMainFrm.Button5Click(Sender: TObject);
begin
ClientModule1.ServerMethods1Client.LongTimeRunFunc(InitCallback, ProgCallback);
end;
二、服務器端實作步驟
在服務器端宣告TServerMethods1的單元檔案uServerMethods中:
1、撰寫一個帶回叫機制的方法
在方法的形參中,帶入客戶端的回叫引數:
function TServerMethods1.LongTimeRunFunc(InitCallback, ProgCallback: TDBXCallback): boolean;
var Max: Integer;
I: Integer;
begin
Max := Random(120) + 1;
InitCallback.Execute(TJSONNumber.Create(Max)).Free; // 將Max值通過JSON格式,通過InitCallback執行回叫后,釋放該物件
for I := 0 to Max do
begin
ProgCallback.Execute(TJSONNumber.Create(I)).Free; // 將I值通過JSON格式,通過ProgCallback執行回叫后,釋放該物件
sleep(1000);
end;
Result := True;
end;
2、宣告該方法
public
{ Public declarations }
function LongTimeRunFunc(InitCallback, ProgCallback: TDBXCallback): boolean;
三、客戶端宣告服務器端輸入方法的物件
服務器端宣告的方法(物件),需要在客戶端中宣告,才能使得二者之間實作資料傳遞。
1、執行服務器端程式。
2、在客戶端的ClientModule1的單元,通過滑鼠右鍵點擊SQLConnection1,選擇“Generate DataSnap client classses”專案。
四、運行機制
客戶端宣告的TProgCallback是繼承TDBXCallback的物件,它復載虛方法Execute,在服務器端運行,接受一個TJSONValue的引數,并且回傳一個TJSONValue的結果值。TDBXCallback的回叫機制很有意思:服務器端在回叫客戶端的方法時,可以將需要回傳緞帶客戶端的值或物件,以TJSONValue的形式,當作虛方法Execute的引數回傳緞帶客戶端,而客戶端的方法,在被回叫執行完畢后,也可以將執行結果,以TJSONValue的形式,回傳給服務器端。
uj5u.com熱心網友回復:
第二篇 回叫信道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
uj5u.com熱心網友回復:
DataSnap 好用么?我都自己寫完成埠服務器來做的。一直信不過DELPHI自己的網路組件,并發過千就不行了uj5u.com熱心網友回復:
服務端::IdTCPServer設定一下DefalutPort;在OnExecute中處理資料(里面有個AThread.引數,AThread.Connection.ReadLn())就可以了
客戶端:IdTCPClient
設定一下host,port即可
clt.Connect();--連接
clt.WriteLn(MSG);--發送資訊
clt.Disconnect;--關閉連接
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/80255.html
標籤:網絡通信/分布式開發
上一篇:新手求助,設計登陸問題
