请问如何在三层中(用SOCKETCONNETION)实现CALLBACK,从而可以回调客户端的函数?(100分)

  • 主题发起人 主题发起人 http1
  • 开始时间 开始时间
我再加100分
 
没有这样试过。也不知道是否可行。
但是如果根据中间层返回的参数然后在客户端做某个操作效果不也一样吗?
能具体说明你想实现什么功能吗?
 
例如,我想在数据改变后通知其他客户去刷新,而不是用程序去定时刷新,我也不想用SOCKET连接。
 
曾研究过这个东西,未果
 
那也是有办法的。首先在客户端定义一个接口,连接服务器时把接口传给服务器。
服务器通过这个接口调用客户端的过程。这样行了吧?
 
服务器通过这个接口调用客户端的过程,怎么实现?是否可以给个例子
 
非常关注!mail to me :cjf@yarnet.com
 
推荐一篇文章
今天下午试通,没有问题
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 todo
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 formdo
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 methoddo
es whatever it is you want todo
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.
Dave

 
首先,谢谢你,可是,怎么通知其他人呢?这只是可以通知自己?
 
-)怎么通知其他人呢?这只是可以通知自己?
应该是所有需要得到服务器通知的客户端都
要这么处理。
 
你好,假设每个客户都怎么处理了,可是,服务器怎么循环处理呢?
例如
FOR I:=0 TO CLIENT.counts-1do
CLIENT RECEIVE MESSAGE
因为IAAPSERVER是无状态的?
 
服务器怎么需要循环处理呢?
每个客户端对应APPSERVER的一个
DATAMODUL,你只需要在DATAMODUL的某个事件
(如某数据集发生变化)里调用客户端的方法就
可以了呀!
 
我是说,每个客户的回调接口只在客户传递上来后,服务器这时再调用客户程序,
但调用完后,就释放了,没有保存,因为IAPPSERVER是无状态的。所以没有办法。
 
上面的方法是静态联编,这就是说,当服务端改变后,客户端又要重新下载新版本?
你说呢?
 
-)每个客户的回调接口只在客户传递上来后,服务器这时再调用客户程序,但调用完后,就释放了,没有保存
回调接口只有在客户端关闭时才释放吧
 
还有SocketConnection 是不支持CallBack的
只有DcomConnection 才可以
 
后退
顶部