如果在创建RemoteDataModule时,选择Instancing为single,那么COM服务器会产生多个内部对象实例来响应多个客户的请求,请问:
如何在这些对象之间通讯,比如:客户A怎么知道客户B对应的对象实例的句柄,并进而可以向那个对象实例发消息?

解决方案 »

  1.   

    选择Instancing为single时,每次有一个客户连接时就会有一个新的服务端程序程序被创建..而不是创建一个新的COM对象.当你设为MultiInstance时才是你说的"COM服务器会产生多个内部对象实例来响应多个客户的请求";
    在delphi中的MIDAS对象一般是无状态对象.所以它并不保存客户端信息..你为什么要在两个对象直接通信呢..
      

  2.   

    如果创建了两个COM对象.这是其实一个是另外一个的拷贝.他们是相同的.就连GUID都是相同的,并且生存期也是动态的.
    我认为没有相互通信的必要啊...当然这只是我的菜鸟看法..呵呵..
      

  3.   

    摩托又来了 :)
    ^_^
    企鹅说的不错,我补充
    (纯属摩托个人观点,如果我是错误的后面来的大侠请用力笑我):
    动态com不能直接捕获消息,你的这个想法估计走不通
    (如果后面来得大虾不认为我是错的也请用力笑,谢谢)
    简单的数据库访问其实说白了就是一个多个com的数据共享,因为
    只有一个数据库。你可以用类似的想法实现各个实例间的数据共享和
    信息传递。甚至你可以利用全局变量。。^_^
    我没有测试,不知道下面的思路能不能满足要求:定义全局变量:
    count:integer;//当前的实例个数
    一个record 记录数组当前的实例
    record中的域记录每个实例你要的信息,如:
     h :Thandle
     c :Tadoconnection 。
      

  4.   

    Single mode 的COM server是只有一个实例,但是它在内部建立了多个内部实例来响应多个客户的请求,我的问题是如何获得特定内部实例的句柄,比如客户A,B,C同时对COM server进行请求,COM server会创建3个内部实例,这时候A能否知道B,C也在访问COM server?如何才可以让A对B发消息,而不是对所有的内部实例广播消息呢?
      

  5.   

    TO:del_c_sharp(摩托还需骆拉) :]
    我现在就是用全局变量,觉得有点呆。
    呵呵还是感谢大家的关心。再来,点人看看,侃侃。
      

  6.   

    MyNameIs007(兰企鹅) :
    没有状态我可以给它加上代表客户状态的域啊,也许是我理解有误,但我觉得对于安全的访问(防止未授权的访问)来说可能还是有必要的。
      

  7.   

    tmSingle       
      COM服务端对象由客户端发出请求,每个COM对象不支持对线程的运作,即每个客户端请求是一个接一个,连继的,不能有多线程、多个客户端的连接的存在,一个客户端请求完成,下一个客户端才能请求服务。在服务端中只能有一个COM对象、一个客户连接的实例。tmApartment
      这种类型确保了在同一时刻只能向所有的COM对象中的一个发出一个请求。
      在每一个客户端实例调用COM对象,服务端将分配一个COM实例给这个客户端,即COM对象和客户端实例是一一对应,所以这些实例的数据是线程安全的.而全局的数据变量必须用Critical Section(临界资源)或相同的功能将它保护起来访问。(线程变量(threadvar)能够在这里使用)---------------
    上面是我大概译的Delphi帮助,我的理解和你贴子的意思不是一样,你看看。
    tmSingle类型中,COM服务器中只是产生一个COM对象为所有的客户进行服务,而不是多个。
      

  8.   

    tmSingle       
      COM serializes all client requests. The object does not need to provide thread support.tmSingle的help原文如上
      

  9.   

    由于我没有说清楚,所以各位大侠的回答也对不上号:
    我的问题是讨论Instancing为single的情况,而不是Threading model;
    好吧,假设在Instancing为single,Threading model Apartment,有什么办法吗?
    关于Instancing为single的情况:
    indicates that, even when several client application require the COM object,there is only one instance of the server application; it create multiple internal object to service requests.
    基本可以译作:
    表示即使有几个客户端应用请求该COM对象,但只存在一个服务器应用的实例,它创建多个内部对象为(客户)请求提供服务。
      

  10.   

    嘿,你那几句help我怎么都没找到,你是在哪找到的?我看到的是:
    (新建RDM中向导中显示)
    Single Instance(ciSingleInstance) 
      Only a single instance of the remote data module is created for each executable. Each client connection launches its own instance of the executable. The remote data module instance is therefor dedicated to a single client.或者是:(查看TClassInstancing关键字帮助)
      Allows only a single instance of the COM object for each executable (application).  If this single instance is not shared across multiple clients, then each client must launch its own instance of the executable. 看一下上面的help,大概都是说只是创建一个实例在服务端,一般是专为了某个客户的连接,如果有多个客户连接的话,那么它们的请求将是串行的运行在服务的实例上。
      你那些英文是不是ciInternal的?三层中一般都可以理解成一个中间代理,My COM Server, My Application组成的应用,最简单的理解方式的SocketConnection and ScktSrvr的组合。
    它们的过程是:
      SocketConnection send command to ScktSrvr
      ScktSrvr.Receive Command and Interpreter Command
        case Command of 
          CreateCom: Obj := CreateOleObject...
          InvokeCom: Obj.Invoke(param...);
          FreeCom: Obj := null;
        end;
      Send Result to Client大概就是这样的流程,DCOM也差不多,只不过它的中间代理是:RPC.exe之类的东西,将安全之类的东西集成到了OS,所以我们配置麻烦多多。  在上面的流程中,可以看到Client App是通过Socket或是某种协议与中间代理进行通讯后,才能够与COM进行通话,并且以上操作都属于:Server以被动的形式与client进行的,所以(现在我是想不通)不太可能说你知道某个Client的实例,然后通过Server去发个消息给另一Client。或者在Server端你知道了某个Client实例,然后你调用实例的方法就可以将消息返回给client,不可能嘛。Client是通过代理Socket/DCOM来访问的,不可能说Server又通过Socket/DCOM去访问Client,这什么跟什么嘛。  因为你的是Single模式,所以我认为在COM Server中只会创建一个RDM,如果有多个RDM的话,到可以将A客户的信息先保存下来,其它Client可以定时来取信息,这样我觉得行的通。不然的话,自已写中间代理了
      

  11.   

    那不是帮助里的,是Mastering d6里的,我也反复看过帮助,把multi和single的帮助内容对比一下,觉得Macro Cantu说的还是有道理。