乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      DataSnap的CallBack

       aaie_ 2014-01-18

      DataSnap可以用TDBXCallBack的類進(jìn)行服務(wù)端和客戶端以及客戶端與客戶端之間的通信。

      在進(jìn)行通信時(shí)要用到以下標(biāo)識(shí)

      服務(wù)端與客戶端通信:

          1.通道 

          2.客戶端注冊(cè)的回叫標(biāo)識(shí)

      客戶端與客戶端通信:

         1.通道

         2.客戶端注冊(cè)的回叫標(biāo)識(shí)

         3.客戶端標(biāo)識(shí)

      一個(gè)客戶端一般只需要一個(gè)通道即可,一個(gè)通道可以注冊(cè)多個(gè)客戶端回叫標(biāo)識(shí),客戶端標(biāo)識(shí)主要用于客戶端通信

      開(kāi)發(fā)時(shí)大體的步驟有以下幾點(diǎn):

      1.服務(wù)端

           用DSServer的BroadcastMessage函數(shù)進(jìn)行發(fā)送信息

      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;

      第一個(gè)函數(shù)時(shí)向ChannelName通道的所有在線客戶端發(fā)送信息,第二個(gè)函數(shù)時(shí)向ChannelName通道的CallBackID的客戶端發(fā)送信息,Msg是要發(fā)送的信息載體。

      2.客戶端

        主要用到了TDSClientCallbackChannelManager類和TDSAdminClient類(DSProxy單元)及TDBXCallBack類。

        1).在工具箱是拖動(dòng)DSClientCallbackChannelManager控件到窗體上,設(shè)置它的channelName\DSHostName\CommuncationProtocol\DSPort\ManagerID屬性等,然后用它的RegisterCallback事件向服務(wù)器注冊(cè)回叫標(biāo)識(shí)即可。

       2) TDSAdminClient類主要用于向其它客戶端發(fā)送信息,主要用到此類的NotifyCallback函數(shù)

      function NotifyCallback(ClientId: string; CallbackId: string; Msg: TJSONValue; out Response: TJSONValue): Boolean; overload;
      function NotifyCallback(ChannelName: string; ClientId: string; CallbackId: string; Msg: TJSONValue; out Response: TJSONValue): Boolean; overload; deprecated 'ChannelName is no longer required';

      msg要發(fā)信息的載體,Response是接收放的應(yīng)答信息,主要是用到了客戶端的TDBXCallBack類,此類這些通信的基礎(chǔ)。

      3)TDBXCallBack是個(gè)虛函數(shù),需用戶重新產(chǎn)生一個(gè)子類并實(shí)現(xiàn)它的Execute的方法。服務(wù)端或客戶端在通信時(shí)會(huì)把這個(gè)子類當(dāng)做參數(shù)進(jìn)行傳遞。

      以下為開(kāi)發(fā)實(shí)例的載圖及其代碼:(最上面的窗體為服務(wù)端,右邊的為客戶端在虛擬機(jī)中,左下邊的為本機(jī)的客戶端)

      以下為開(kāi)發(fā)大體步驟:

      1.開(kāi)發(fā)服務(wù)端

      菜單"File-New-Other-DataSnap Server "建立服務(wù)端程序,主要在主窗體上放上以下幾個(gè)控件:

      兩個(gè)listbox,主要獲取客戶端所有的回叫標(biāo)識(shí)和客戶端標(biāo)識(shí),兩上TRadioButton用于發(fā)送信息時(shí)確認(rèn)是給同一通道的客戶發(fā)信息還是給指定的回叫標(biāo)識(shí)發(fā)信息,這里主要用到了TJSONValue

      以下為服務(wù)端主界面的源碼

      復(fù)制代碼
      unit UFrmServer;
      
      interface
      
      uses Winapi.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: TButton;
          rbAll: TRadioButton;
          rbSingle: TRadioButton;
          GroupBox1: TGroupBox;
          btnAllClientID: TButton;
          lbClientID: TListBox;
          procedure btnAllCallBackIDClick(Sender: TObject);
          procedure btnAllClientIDClick(Sender: TObject);
          procedure btnSendClick(Sender: TObject);
      
          procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
        private
          { Private declarations }
        public
          { Public declarations }
        end;
      
      var
        Form1: TForm1;
      
      implementation
      uses ServerContainerUnit1,System.Generics.Collections,Data.DBXJSON;
      {$R *.dfm}
      
      const channel='test';
      
      procedure TForm1.btnAllCallBackIDClick(Sender: TObject);   //獲取所有通道的回叫標(biāo)識(shí)
      var
        ls:TList<string>;
        ea:TList<string>.TEnumerator;
      begin
        lbCallBackID.Clear;
        ls:=ServerContainerUnit1.ServerContainer1.DSServer1.GetAllChannelCallbackId(channel);
        ea:=ls.GetEnumerator;
        while ea.MoveNext do
        lbCallBackID.Items.Add(ea.Current);
        ls.Free;
      end;
      
      procedure TForm1.btnAllClientIDClick(Sender: TObject);  //獲取所有通道的客戶端標(biāo)識(shí)
      var
        ls:TList<string>;
        ea:TList<string>.TEnumerator;
      begin
        lbClientID.Clear;
        ls:=ServerContainerUnit1.ServerContainer1.DSServer1.GetAllChannelClientId(channel);
        ea:=ls.GetEnumerator;
        while ea.MoveNext do
          lbClientID.Items.Add(ea.Current);
        ls.Free;
      end;
      
      procedure TForm1.btnSendClick(Sender: TObject);   //發(fā)送信息
      var
        js:TJsonString;
        callid:string;
      begin
        js:=TJSONString.Create(edtMessage.Text);
        if rbAll.Checked then
          ServerContainer1.DSServer1.BroadcastMessage(channel,js)
        else
        begin
          callid:=lbCallBackID.Items.Strings[lbCallBackID.ItemIndex];
          if callid<>'' then
            ServerContainerUnit1.ServerContainer1.DSServer1.BroadcastMessage(channel,callid,js);
      
        end;
      
      end;
      
      
      
      procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
      begin
        if MessageDlg('你要關(guān)閉服務(wù)嗎?',mtInformation,[mbYes,mbNo],0,mbno)=idno then
          CanClose:=False
        else
        begin
           if ServerContainerUnit1.ServerContainer1.DSServer1.Started then
             ServerContainerUnit1.ServerContainer1.DSServer1.Stop;
           CanClose:=True;
        end;
      
      end;
      
      end.
      復(fù)制代碼

      2.開(kāi)發(fā)客戶端

      建立應(yīng)用程序并在菜單"File-New-DataSnap Server"選擇DataSnap Client Module選項(xiàng),連接上面建立的服務(wù)程序并自動(dòng)產(chǎn)生服務(wù)端的導(dǎo)出函數(shù)單元及DataModule類,在DataModule類上放TDSClientCallbackChannelManager控件,它主要用于向服務(wù)端注冊(cè)回叫標(biāo)識(shí),另它的ManagerID是用于客戶端的標(biāo)識(shí),千萬(wàn)不要忘記它的相關(guān)屬性設(shè)置,否則其它電腦上的客戶端是無(wú)法訪問(wèn)服務(wù)端的。

      在客戶端主界面上放以下控件:

      TMemo:用于顯示收到的信息

      兩個(gè)Combobox,讓用戶輸入其它客戶端的回叫ID和客戶端標(biāo)識(shí)ID,用于給其它客戶端發(fā)信息

      一個(gè)Tedit,用于寫(xiě)入要發(fā)送的信息內(nèi)容,一個(gè)button用于發(fā)送動(dòng)作

      兩個(gè)TEdit,主要是讓程序在運(yùn)行時(shí)讓用戶 輸入客戶端標(biāo)識(shí)ID和客戶端回叫ID。

      一個(gè)Tbutton用于手動(dòng)注冊(cè)回叫事件

      另加上一個(gè)TEdit,主要設(shè)置服務(wù)端的地址

      以下為客戶端主界面源碼:

      復(fù)制代碼
      unit UMain;
      
      interface
      
      uses
        Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
        Vcl.Controls, Vcl.Forms, Vcl.Dialogs,Data.DBXJSON, Vcl.StdCtrls, Vcl.ComCtrls;
      
      type
        TFrmClient = class(TForm)
          GroupBox1: TGroupBox;
          mmReceive: TMemo;
          StatusBar1: TStatusBar;
          edtCallBack: TEdit;
          Label1: TLabel;
          Button1: TButton;
          Label2: TLabel;
          edtServer: TEdit;
          GroupBox2: TGroupBox;
          edtSend: TEdit;
          btnSend: TButton;
          Label3: TLabel;
          Label4: TLabel;
          cbCallBack: TComboBox;
          cbClientID: TComboBox;
          label5: TLabel;
          edtClientID: TEdit;
          procedure btnSendClick(Sender: TObject);
          procedure Button1Click(Sender: TObject);
          procedure FormClose(Sender: TObject; var Action: TCloseAction);
          procedure FormCreate(Sender: TObject);
        private
          { Private declarations }
          procedure RegisterCallBackID;
          function ConnectServer:Boolean;
          procedure AddCombobox(const ClientID,CallID:string);
          procedure SendMsgToOtherClient;
        public
          { Public declarations }
        end;
      
      type
        TDataSnapCallBack = class(TDBXCallback)
        private
          { private declarations }
        protected
          { protected declarations }
        public
          { public declarations }
      
          function Execute(const Arg: TJSONValue): TJSONValue;override;
      
        published
          { published declarations }
        end;
      
      
      var
        FrmClient: TFrmClient;
        callid:string;
      const
        channel='test';
      implementation
       uses ClientModuleUnit1,Data.SqlExpr,Data.DBXCommon,Datasnap.DSProxy;
      {$R *.dfm}
      
      function TFrmClient.ConnectServer: Boolean;
      begin
        Result:=false;
      
      
        with ClientModule1.SQLConnection1 do
        begin
          Params.Clear;
          with ConnectionData.Properties do
          begin
            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/';
          end;
          LoginPrompt:=False;
          try
            ClientModule1.SQLConnection1.Open;
            Result:=ClientModule1.SQLConnection1.ConnectionState=csStateOpen;
            ClientModuleUnit1.ClientModule1.DSClientCallbackChannelManager1.DSHostname:=edtServer.Text;//一定要設(shè)置
          except
      
          end;
        end;
      end;
      
      procedure TFrmClient.FormCreate(Sender: TObject);
      begin
      
      end;
      
      { TDataSnapCallBack }
      
      function TDataSnapCallBack.Execute(const Arg: TJSONValue): TJSONValue;
      var
        str:string;
      begin
        Result:=TJSONString.Create('成功回叫客戶端'); //一定要回傳給服務(wù)端信息 ,在客戶端發(fā)送時(shí)會(huì)顯示
        if Assigned(Arg) then
          if (Arg is TJSONString) then
          begin
            str:=TJSONString(Arg).Value;
            TThread.Synchronize(nil,
                                 procedure       //匿名方法
                                 begin
                                   FrmClient.mmReceive.Lines.Add(str);
                                 end
                               );
          end;
      
      end;
      
      procedure TFrmClient.AddCombobox(const ClientID,CallID:string);
      begin
        if cbClientID.Items.IndexOf(clientID)=-1 then
        cbClientID.Items.Add(ClientID);
        if cbCallBack.Items.IndexOf(CallID)=-1 then
        cbCallBack.Items.Add(CallID);
      end;
      
      procedure TFrmClient.btnSendClick(Sender: TObject);
      begin
        SendMsgToOtherClient;
      end;
      
      procedure TFrmClient.Button1Click(Sender: TObject);
      begin
        if (edtCallBack.Text='') or (edtClientID.Text='') then
        begin
          ShowMessage('請(qǐng)輸入相關(guān)標(biāo)識(shí).');
          exit;
        end;
      
      
        RegisterCallBackID;
      end;
      
      procedure TFrmClient.FormClose(Sender: TObject; var Action: TCloseAction);
      begin
        if ClientModuleUnit1.ClientModule1.SQLConnection1.ConnectionState=csStateOpen then
        begin
          ClientModule1.DSClientCallbackChannelManager1.UnregisterCallback(callid);
          ClientModule1.SQLConnection1.Close;
        end;
      end;
      
      procedure TFrmClient.RegisterCallBackID;
      var
        i:Integer;
      begin
       // callid:=DateTimeToStr(now);
        AddCombobox(edtClientID.Text,edtCallBack.Text);
       callid:= edtCallBack.Text;
       ClientModule1.DSClientCallbackChannelManager1.ManagerId:=edtClientID.Text;
        if ConnectServer then
        begin
          StatusBar1.Panels[0].Text:='已成功連接服務(wù)器';
      
          if   ClientModule1.DSClientCallbackChannelManager1.RegisterCallback(callid,TDataSnapCallBack.Create) then
                StatusBar1.Panels[1].Text:='已成功注冊(cè),CallID:'+Callid
          else
            StatusBar1.Panels[1].Text:='注冊(cè)CallID失敗.';
        end else
        begin
         StatusBar1.Panels[0].Text:='連接服務(wù)器失敗';
          i:=cbCallBack.Items.IndexOf(callid);
          cbCallBack.Items.Delete(i);     //刪除注冊(cè)失敗的id
        end;
      end;
      
      procedure TFrmClient.SendMsgToOtherClient;
      var
        AC:TDSAdminClient;  //發(fā)送消息管理類
        vMessage:TJSONString;
        outMessage:TJSONValue;
        clientID,CallbackID,sMessage:string;
      begin
        if ConnectServer then
        begin
          clientID:=cbClientID.Text;
          CallbackID:=cbCallBack.Text;
          AC:=TDSAdminClient.Create(ClientModule1.SQLConnection1.DBXConnection,False);
          sMessage:=Format('呼叫通道: %s, 回叫識(shí)別: %s, 客戶端標(biāo)識(shí): %s, 發(fā)送信息: %s',[channel,callbackid,clientid,edtSend.Text]);
          try
             vMessage:=TJSONString.Create(sMessage);
             try
               AC.NotifyCallback(channel,clientID,CallbackID,vMessage,outMessage);
               try
                  if Assigned(outMessage) then
                    mmReceive.Lines.Add(Format('返回信息: %s',[outmessage.ToString]))
                  else
                   mmReceive.Lines.Add('對(duì)方?jīng)]有回應(yīng)') ;
               finally
                 outMessage.Free;
               end;
      
             finally
                vMessage.Free;
             end;
      
          finally
            AC.Free;
          end;
      
        end;
      
      end;
      
      
      
      
      end.
      復(fù)制代碼

       

      在XE3下開(kāi)發(fā),用tcp/ip

      源碼下載地址:http://download.csdn.net/detail/yagzh2000/5303997

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多