客户端定时轮询就不要说啦。

解决方案 »

  1.   

    没人回,自己帖吧,以下是解决方案,没时间翻译啦,其实听好理解的。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 unitvar
        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. IServer4.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.Dave
    中心思想是客户端和服务器都声明同一个接口,但实现是在客户端。服务器向客户端发消息,其实就是调用客户端的函数。客户端生成一个本地接口指针并传给服务器,服务器用它来调客户端的函数。
    不过还有些不明白,尤其是那几个中心语句和变量的作用,哪位给讲讲。注:文章摘自大富翁离线数据库。小小,分可怎么给啊!
      

  2.   

    呵呵,回调的确可以~~~
    摩托更喜欢直接socket,客户是server,代码要写不少,但很灵活
      

  3.   

    摩托说得很正确,现在是服务器端还要接收socket端口的消息,然后根据消息发往不同的客户端,怎么在无状态下维护客户的接口指针?唉!都是问题啊!哪位高手解决一下。
      

  4.   

    摩托,再帖点有用的我就结贴,要不然分给谁啊?告诉我多个接口间怎么调用,我老是在一个接口中create另一个接口的指针。
    这样对吗?我怎么觉得不太合适?我要访问多个接口,也要create多个接口指针吗?
      

  5.   

    回调的问题会很多,还不如用SOCKET
      

  6.   

    能说说回调隐藏的问题吗?
    不过我现在就有一个啦。
    客户端用了一个ActiveX,ActiveX有一个Form1:TForm,回调函数无法访问Form1里的内容。我用Showmessage可以打出回调的参数,可是Form1.edit1.text就不显示,怎么回事呢?第二个问题。我有3个接口,一个是Transactional Object,另两个是Transactional Data Module。我现在要在Transactional Object内访问另外两个Transactional Data Module,我是不是要创建两个接口指针?我看有的代码是这样写,从一个IUnknown中as出接口指针。例:pUnkSite: IUnknown;
    pOleWindow:IOleWindow;
    m_pSite:IInputObjectSite;m_pSite:=pUnkSite as IInputObjectSite;
    pOleWindow := PunkSIte as IOleWindow;我能这样做吗?哪些代码是怎么做的?回答一个问题得50分,分等回答出后再加。期待中……