CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
可用分押宝游戏火热进行中... 专题改版:Java Web 专题
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  C++ Builder >  网络及通讯开发

DCOM回调?

楼主MEFULEU(没有作不到,只有想不到)2005-04-04 12:45:47 在 C++ Builder / 网络及通讯开发 提问

由于服务器端有一个很漫长的过程A(1分多种),如果在客户端调用,就像死机一样,我想先让客户端调用一个服务器的另一个过程B来激活这个A过程;服务器执行完A再发送消息给客户端来读取数据.那么想从服务器中返回消息给客户端;必须怎样做才可以. 问题点数:100、回复次数:6Top

1 楼constantine(飘遥的安吉儿)回复于 2005-04-04 16:30:48 得分 0

阅Top

2 楼NetSpider9804040(网络蛛蛛)回复于 2005-04-04 17:52:39 得分 0

关注!Top

3 楼MEFULEU(没有作不到,只有想不到)回复于 2005-04-05 08:45:03 得分 0

以前看到一些e文资料,但是e文水平有限....谁帮我翻译一下  
  There   is   also   a   way   for   the   server   to   call   methods   on   the   client.   Its   a    
  little   involved   to   set   up   and   I   have   not   tried   it   myself,   however,   the    
  following   is   how   to   do   it   :    
   
  Server    
  -------    
  1).   In   the   server   _TLB   unit,   create   a   new   interface,   lets   call   it   IClient.    
  2).   After   adding   this,   expand   its   tree   and   add   any   client   methods   that   will    
  be   called.   For   example,   lets   add   a   method   called   SendRecordsProcessed   which    
  takes   one   parameter   NumberRecords   of   type   Integer.    
  3).   Now   expand   the   main   RemoteDataModule   interface   to   add   a   new   server    
  automation   method   called   ConnectClient   which   takes   one   parameter,   IClient.    
  4).   ConnectClient   assigns   its   interface   reference   parameter   to   a   variable    
  that   is   added   to   the   remote   data   module,   so,   edit   that   RemoteDataModule's    
  unit   and   add   a   private   variable   ClientConnection   of   type   IClient.   In   other    
  words,   ClientConnection   is   the   server's   reference   to   the   object   that    
  implements   the   IClient   interface   with   the   client.   With   this   interface    
  reference   the   server   can   call   any   method   of   the   interface.    
  5).   Insert   this   new   method's   implementation   code   as   follows   :    
                        procedure   TServer.ConnectClient(const   Client:   IClient);    
                        begin    
                                          ClientConnection   :=   Client;    
                        end;    
  6).   In   your   server   you   must   have   a   procedure(s)   or   function(s)   which   are    
  doing   all   of   this   processing   of   which   you   speak,   so   at   the   end   of   the    
  processing   insert   the   following   call   :    
                ClientConnection.SendRecordsProcessed(   <NumberOfRecords   >   );    
  So   this   is   using   the   interface   reference   to   call   the   SendRecordsProcessed    
  method   in   the   client   app.    
   
   
  Client    
  -------    
  We   must   now   add   the   client   side   processing   necessary,   ie.   an   object   that    
  implements   the   IClient   interface.   In   your   main   form   do   the   following   :    
   
  1).   Declare   the   client   side   object   that   implements   the   IClient   interface    
   
                    TCallBack   =   class(   TAutoIntfObject,   IClient   )    
                              procedure   SendRecordsProcessed(   const   NumberRecords:    
  Integer   );   safecall;    
                    end;    
   
  The   TCallback   object   descends   from   TAutoIntfObject   which   provides   support    
  for   the   IDispatch   interface.   The   implementation   code   for   the    
  SendRecordsProcessed   method   does   whatever   it   is   you   want   to   do   with   that    
  number   of   records   processed,   ie.   display   it   in   a   message   box   or   on   a   form,    
  so   I'll   leave   that   up   to   you.    
   
  2).   Include   the   server's   _TLB   unit   in   the   uses   clause   of   the   main   form.    
   
  3).   Variable   declarations   global   to   the   main   form's   unit    
   
  var    
          ServerTypeLib:               ITypeLib;    
          TypeLibResult:                 HResult;    
          CallBack:                                 IClient;    
   
  4).   Build   the   heart   of   the   callback   mechanism   in   the   OnCreate   event   handler    
  of   the   client   app's   main   form.    
   
  procedure   TMainForm.FormCreate(Sender:   TObject);    
  var    
          Srvr:                 <ServerInterfaceName>;                         //   Name   as   defined   in   the    
  server   TLB,   eg.   IServer    
   
  4.1).   Call   the   Windows   API   function   LoadRegTypeLib   to   load   the   server's   type    
  library.   The   parameters   are   :    
   
                    The   type   library's   GUID,   definied   as   a   constant   LIBID_XXX   in   the    
  server's   TLB   unit    
                    The   type   library's   major   version   number    
                    The   type   library's   minor   version   number    
                    The   national   language   code   of   the   library    
                    An   interface   reference   variable   of   the   type   ITypeLib   that   is    
  initialised   by   the   call    
                    to   point   to   the   type   library   (   ServerTypeLib   var   above   )    
   
                        TypeLibResult   :=   LoadRegTypeLib(   LIBID_XXX,   1,   0,   0,    
  ServerTypeLib   )    
   
  4.2).   Check   the   result   of   the   LoadRegTypeLib    
   
                        If   TypeLibResult   <>   S_OK   Then    
                        Begin    
                                        ShowMessage(   'Error   loading   type   library'   );    
                                        Exit;    
                        End;    
   
  4.3).   Create   an   instance   of   the   TCallback   automation   object.   The   type    
  library   and   interface   that   the   TCallBack   object   implements   are   passed   as    
  parameters   to   its   constructor   and   the   returned   value   is   assigned   to   the    
  interface   reference   variable   CallBack.    
   
                        CallBack   :=   TCallBack.Create(   ServerTypeLib,   IClient   );    
   
  4.4).   Next,   obtain   a   reference   to   the   server's   interface   IClient   by   casting    
  the   DComConnection   (   MidasConnection   )   AppServer   property   to   the   interface    
  type.    
   
                        Srvr   :=   IDispatch(   <DataModule>.<DComConnection>.AppServer   )   as    
  <ServerInterfaceName>;    
   
  4.5).   Finally   call   the   server's   ConnectClient   automation   method,   passing   the    
  interface   reference   variable   for   the   TCallBack   object.    
   
                        Srvr.ConnectClient(   CallBack   );    
   
   
  I   apologise   in   advance   if   I   have   mis-typed   or   left   anything   out,   but   it    
  should   be   a   good   enough   starting   point.    
   
  DaveTop

4 楼lidawen(Darwin)回复于 2005-04-05 08:46:53 得分 0

學習Top

5 楼MEFULEU(没有作不到,只有想不到)回复于 2005-04-05 12:57:58 得分 0

高手呢?都转行了吗?Top

6 楼lanren_me(阿波)回复于 2005-04-08 09:03:48 得分 100

今天试验成功了,原来很容易的,过程大约如下:  
   
  客户端:  
  1。在客户端创建一个类型库,添加一个用于回调的接口,在其中声明接口方法。  
  2。在客户应用程序中声明一个类,从   TAutoIntfObject   继承,并实现上面添加的回调接口。  
  3。客户应用程序启动时创建这个类,然后调用中间层的一个接口方法,该方法把用于回调的接口传递给中间层。  
   
  中间层:  
  1。在中间层的类型库中添加一个接口方法,客户端通过调用此方法把回调接口传递给中间层。其形式为:procedure   SetCallback(ACallback:OleVariant);  
  2。在该接口方法的实现代码中,把客户端传递来的接口用一个本地的   OleVariant   变量(如FCallback:=ACallback)保存。  
  3。在需要回调时,执行:FCallback.AMethod(...)。  
   
   
  用这种方式,客户端也同时作为   COM   服务器了吧,配置每个客户端可能也是比较麻烦的事情。  
   
   
   
   
  unit   ClientM;     /////////客户端窗体;  
   
  interface  
   
  uses  
      Windows,   Messages,   SysUtils,   Variants,   Classes,   Graphics,   Controls,   Forms,  
      Dialogs,   StdCtrls,ComObj,Server_TLB,MConnect,   DB,   DBClient,   SConnect,ActiveX,  
      ComServ;  
   
  type  
      TClientCallBack   =   Class(TAutoIntfObject   ,   IDCOMBackCalls)  
          procedure   SetInfo(var   InfoName:   OleVariant;   var   InfoPass:   OleVariant);   safecall;  
      end;  
   
      //////////////////////////////////////////////////////////////////////////////  
      //////////TClientCallBack   =   Class(TAutoIntfObject,IDCOMBackCalls)   TClientCallBack   它继承类TAutoIntfObject  
      //////////同时又是实现了接口IDCOMBackCalls,而这个接口是需要在TypeLib中声明的;  
      ///////////接口的实现,需要知道,之后还要进行类的实例化;  
      ///////////需要实现这个接口的方法 :SetInfo(.....)   SafeCall   ,注意,这儿只能用SafeCall;  
      //////////下边有接口的实例化,FClientCallBack   :   TClientCallBack;  
      //////////uses   ComObj;  
      ///////////////////////////////////////////////////////////////////////////////////  
      TForm2   =   class(TForm)  
          Button1:   TButton;  
          Label1:   TLabel;  
          Label2:   TLabel;  
          Label3:   TLabel;  
          Edit1:   TEdit;  
          Edit2:   TEdit;  
          Edit3:   TEdit;  
          SocketConnection1:   TSocketConnection;  
          procedure   Button1Click(Sender:   TObject);  
          procedure   FormCreate(Sender:   TObject);  
      private  
          FClientCallBack   :   TClientCallBack;  
          /////////这一句是接口正真的实例化;  
          {   Private   declarations   }  
      public  
          MyDCOMConnection   :   TDispatchConnection;  
          //////注意这一句:TDispatchConnection   是如下定义的:  
          //////TDispatchConnection   =   class(TCustomRemoteServer)  
          {   Public   declarations   }  
      end;  
   
  var  
      Form2:   TForm2;  
      ClientVar   :   IDCOMServerSL1;  
      //////////////////////////////////////////////////////////////////////////////  
      //////定义一个接口,是TypeLib中声明的哦;uses   Server_TLB,(User   TypeLib)  
      //////////////////////////////////////////////////////////////////////////////  
   
  implementation  
   
   
  {$R   *.dfm}  
   
  procedure   TForm2.Button1Click(Sender:   TObject);  
  begin  
      ClientVar   :=   CoDCOMServerSL1.Create;  
      if   ClientVar.GetInfo(Edit1.Text,Edit2.Text)   then  
      begin  
          Application.MessageBox('恭喜您,登录成功!','操作提示',MB_OK   +   MB_ICONINFORMATION);  
      end   else  
      begin  
          Application.MessageBox('对不起,登录失败!','操作提示',MB_OK   +   MB_ICONINFORMATION);  
      end;  
      /////////////////////////////////////////////////////////////////////////////////////  
      /////////MyDCOMConnection.AppServer.ProcName;,也可以用这种进行回调  
      /////////CoDCOMBackCall   =   class  
      /////////class   function   Create:   IDCOMBackCall;  
      ////////class   function   CreateRemote(const   MachineName:   string):   IDCOMBackCall;  
      ////////end;  
      ////////看一看它的定义,它其实是一个类,呵呵,协同接口类;是实现一个或多个接口的类,  
      ///////有一个类生成库和一个类标识器;  
      ///////这一部分是DCOM的,和回调无关;  
      ///////////////////////////////////////////////////////////////////////////////////////  
  end;  
   
  {   TClientCallBack   }  
   
   
  procedure   TForm2.FormCreate(Sender:   TObject);  
  var  
      TypeLib   :   ITypeLib;  
  begin  
      MyDCOMConnection   :=   SocketConnection1;  
      MyDCOMConnection.Connected   :=   True;  
      OLECheck(LoadRegTypeLib(LIBID_Server,0,0,1,TypeLib));  
      MyDCOMConnection.AppServer.GetInfos(FClientCallBack   as   IDispatch);  
      {/////////////////////////////////////////////////////////////////////////////  
      //////MyDCOMConnection   :=   SocketConnection1;是回调的关键,你要用它来代替TSocketConnection,操作还是类实例之间,你明白吗?  
      //////MyDCOMConnection.Connected   :=   True;还用说吗?  
      //////OLECheck(LoadRegTypeLib(LIBID_Server,0,0,1,TypeLib));在客户端注册;  
      //////MyDCOMConnection.AppServer.GetInfos(FClientCallBack   as   IDispatch);开始执行,而且进行接口转化;  
      //////TypeLib   :   ITypeLib;可以应用类型库类   Uses   ActiveX;  
      //////////////////////////////////////////////////////////////////////////////}  
  end;  
   
  {   TClientCallBack   }  
   
  procedure   TClientCallBack.SetInfo(var   InfoName,   InfoPass:   OleVariant);  
  begin  
      ShowMessage(InfoName);  
      ShowMessage(InfoPass);  
      {/////////////////////////////////////////////////////////////////////////////  
      /////我不知道你是否知道RDM中是如果引用接口的,这和它是一样的;  
      //////////////////////////////////////////////////////////////////////////////}  
  end;  
   
  end.  
  unit   ServerRDM;   ////////远程数据模块,是回调机制用的,于DCOM无关;  
   
  {$WARN   SYMBOL_PLATFORM   OFF}  
   
  interface  
   
  uses  
      Windows,   Messages,   SysUtils,   Classes,   ComServ,   ComObj,   VCLCom,   DataBkr,  
      DBClient,   Server_TLB,   StdVcl;  
   
  type  
      TDCOMBackCall   =   class(TRemoteDataModule,   IDCOMBackCall)  
      private  
          BackCallSL   :   OleVariant;  
          {   Private   declarations   }  
      protected  
          class   procedure   UpdateRegistry(Register:   Boolean;   const   ClassID,   ProgID:   string);   override;  
          procedure   GetInfos(var   Infos:   OleVariant);   safecall;  
      public  
          {   Public   declarations   }  
      end;  
   
  implementation  
   
  {$R   *.DFM}  
   
  class   procedure   TDCOMBackCall.UpdateRegistry(Register:   Boolean;   const   ClassID,   ProgID:   string);  
  begin  
      if   Register   then  
      begin  
          inherited   UpdateRegistry(Register,   ClassID,   ProgID);  
          EnableSocketTransport(ClassID);  
          EnableWebTransport(ClassID);  
      end   else  
      begin  
          DisableSocketTransport(ClassID);  
          DisableWebTransport(ClassID);  
          inherited   UpdateRegistry(Register,   ClassID,   ProgID);  
      end;  
  end;  
   
  procedure   TDCOMBackCall.GetInfos(var   Infos:   OleVariant);  
  begin  
      BackCallSl   :=   Infos;  
      BackCallSl.SetInfo('a','b');  
      {////////////////////////////////////////////////  
      ///////BackCallSl   :=   Infos;(还记得这个参数传过来的是什么吗?呵呵,看前边去;)  
      /////回调,可以由任意事件进行激发  
      /////////////////////////////////////////////////     }  
  end;  
   
  initialization  
      TComponentFactory.Create(ComServer,   TDCOMBackCall,  
          Class_DCOMBackCall,   ciMultiInstance,   tmApartment);  
   
   
  Top

相关问题

  • DCOM 调用
  • DCOM
  • DCOM组件的调用
  • DCOM远程调用问题
  • 怎样调DLL,COM,DCOM
  • .net 下如何调用dcom
  • ASP中能调用DCOM对象吗
  • 请问VBScrpit如何调用DCOM组件?
  • asp中调用DCOM的问题
  • 谁能帮我调一下DCOM程序?

关键词

  • 接口
  • 客户
  • mydcomconnection
  • tclientcallback
  • iclient
  • idcombackcall
  • tautointfobject
  • loadregtypelib
  • olevariant
  • 中间层

得分解答快速导航

  • 帖主:MEFULEU
  • lanren_me

相关链接

  • CSDN Blog
  • 技术文档
  • 代码下载
  • 第二书店
  • 读书频道

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
世纪乐知(北京)网络技术有限公司 版权所有, 京 ICP 证 020026 号
北京创新乐知广告有限公司 提供技术支持
Copyright © 2000-2007, CSDN.NET, All Rights Reserved
GongshangLogo