• datasnap的回调广播


    感觉中的datasnap千孔百疮,到xe10已经具备冲击成千上万用户并发的能力了。应该放心用于项目实战了。补课研究10.1 datasnap开发手册。

    用到的方法:

        (1)TDBXCallback机制;
        (2)TDServer.BroadcastMessage方法;
        (3)TDSClientCallbackChanneManager1.RegisterCallback方法;

        一、回叫的方式
        1、服务器端回叫所有(同一信道)客户端
        2、客户端回叫(同一信道)的其它客户端                                                                       
        3、客户端可以注册多个信道

    server:

    1.   定义信道。定一条通道公路,然后搜索在此通道上跑的的car。得到每个客户ID
    const DEMOChannel='DemoChannel';

            2.服务器对客户端回调:

    procedure TSMainFrm.mmMessageChange(Sender: TObject);
    var vMessage:TJSONString;
    begin
      vMessage := TJSONString.Create(mmMessage.Lines.Text);
      ServerContainer1.DSServer1.BroadcastMessage(DEMOChannel, vMessage);
    end;

           3.对客户端注册通道和回调通道的搜索,由此得到通道中客户端的ID

    procedure TForm1.btnListAllClientIdsClick(Sender: TObject);
    var
      aIdList : TList<String>;
      sId : String;
    begin
      aIdList := ServerContainer5.DSServer1.GetAllChannelClientId(DEMOChannel);{得到该通道中all的客户端ID}
      try
        for sId in aIdList do
          lbAllClientIds.Items.Add(sId);
      finally
        aIdList.Free;
      end;
    end;
    procedure TForm1.btnListAllCallbackIdsClick(Sender: TObject);
    var
      aIdList : TList<String>;
      sId : String;
    begin
      aIdList := ServerContainer5.DSServer1.GetAllChannelCallbackId(DEMOChannel);{得到该回调通道中all的客户端ID
      try
        for sId in aIdList do
          lbAllCallbackIds.Items.Add(sId);
      finally
        aIdList.Free;
      end;
    end;

    Client:

           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方法,就是用于回叫识别。

    //首先继承类TDBXCallback 
    TDemoCallback = class(TDBXCallback) public constructor Create; function Execute(const Arg: TJSONValue): TJSONValue; override; end;
    //TDemoCallback的excute方法。注意线程异步调用
    function
    TDemoCallback.Execute(const Arg: TJSONValue): TJSONValue; var sDemoMessage : String; begin Result := TJSONTrue.Create; if (Arg is TJSONString) then begin sDemoMessage := TJSONString(Arg).Value; TThread.Synchronize(nil, procedure begin fmMainForm.mmDemoMessage.Lines.Text := sDemoMessage; end ); end; end;
    procedure TfmMainForm.btnStartClick(Sender: TObject);
    begin
      SetupTask;
      EnableDisableButtons(False, True);
      DemoChannelManager.RegisterCallback(callbackId, DemoCallback.Create);//注册通道
    end;
    
    procedure TfmMainForm.btnStopClick(Sender: TObject);
    begin
      EnableDisableButtons(True ,False);
      DemoChannelManager.UnregisterCallback(callbackId);//注销
    end;
    procedure TForm17.mmMessageChange(Sender: TObject);//服务器通过回调发送信息到该通道all客户端
    var
      vMessage : TJSONString;
    begin
      vMessage := TJSONString.Create(mmMessage.Lines.Text);
      ServerContainer5.DSServer1.BroadcastMessage(DEMOChannel, vMessage);//发送信息到该通道DEMOChannel中all的客户端
    end;

        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;
  • 相关阅读:
    《Effective C#中文版:改善C#程序的50种方法》读书笔记
    WPF总结
    定义集合属性(WPF)
    c#只读字段和常量的区别,以及静态构造函数的使用 .
    编程方法的参数
    关于事件的点滴总结
    线程间的消息(或数据)传递
    OOP的感悟
    VS2010快捷键大全----养成良好的习惯
    UTF-8里包括GB2312
  • 原文地址:https://www.cnblogs.com/usegear/p/12511445.html
Copyright © 2020-2023  润新知