现在的位置: 首页 > 综合 > 正文

.Net Remoting应用中的回调(callback)

2013年08月21日 ⁄ 综合 ⁄ 共 1993字 ⁄ 字号 评论关闭

 在c/s应用中,有时需要从服务端回调客户端的程序,在.Net下,通过事件委托机制可以很简单的进行实现,

 

因为服务端需要调用客户端程序,它必须知道客户端程序的存根(即类定义),

但我们应该对程序逻辑实现进行隔离,即服务端不应该包括客户端具体的实现代码,

在这个前提下,我们引入了一个ServiceAdapter类,定义如下:

  1.     public class ServiceAdapter : MarshalByRefObject
  2.     {
  3.         public event Callback OnCallback;
  4.         public void Callback(object obj)
  5.         {
  6.             if (OnCallback != null)
  7.                 OnCallback(obj);
  8.         }
  9.     }

ServiceAdapter是一个远程对象,这样服务端才能调用它。Callback是一个委派对象,定义如下:

  1. public delegate void Callback(object obj);

回调(callback)的思路

 

在客户端:

创建ServiceAdapter对象,并对OnCallback委派进行赋值,然后把Callback方法传递给服务端;

 

在服务端:

将客户端传递过来的Callback委派方法进行登记,在需要回调客户端时,遍历Callback委派进行调用,

显然,回调是由ServiceAdapter完成的,这也是ServiceAdapter必须是远程对象的原因。

部分实现代码

 

客户端:

  1. IChannel chnl = new TcpChannel(0);
  2. ChannelServices.RegisterChannel(chnl, false);
  3. ServiceAdapter adapter = new ServiceAdapter();
  4. adapter.OnCallback += new Callback(client_OnCallback);
  5. ISomeService ss = (ISomeService)Activator.GetObject(typeof(ISomeService), "tcp://localhost:8080/someservice.rem");
  6. ss.RegisterClient(new Random().Next(1000, 9999).ToString(), adapter.Callback);

第1,2行很重要,用于注册一个信道,用于服务端回调。

 

服务端:

服务注册

  1. BinaryServerFormatterSinkProvider serverProvider = new BinaryServerFormatterSinkProvider();
  2. serverProvider.TypeFilterLevel = TypeFilterLevel.Full;
  3.        
  4. IDictionary dict = new Hashtable();
  5. dict["port"] = 8080;
  6. channel = new TcpChannel(dict, null, serverProvider );
  7. ChannelServices.RegisterChannel(channel, false);
  8. RemotingConfiguration.ApplicationName = "SomeService";
  9. WellKnownServiceTypeEntry service = new WellKnownServiceTypeEntry(typeof(SomeServiceImpl), "SomeService.rem", WellKnownObjectMode.Singleton);
  10. RemotingConfiguration.RegisterWellKnownServiceType(service);

第1,2行为设置安全级别,默认为Low。

回调客户端

  1. IDictionary<string, Callback> temp = new Dictionary<string, Callback>(callbacks);
  2. foreach (string client in temp.Keys)
  3. {  // 遍历所有callback.
  4.     try
  5.     {
  6.         temp[client](obj);
  7.     }
  8.     catch
  9.     {  // 如出现异常,则移除callback登记.
  10.         callbacks.Remove(client);
  11.     }
  12. }

源码下载:http://www.cchensoft.com/down/RemotingCallback.zip

抱歉!评论已关闭.