Microsoft .Net Remoting系列教程之三:Remoting事件处理全(5)

watch = (IBroadCast)Activator.GetObject( typeof(IBroadCast),"http://localhost:8080/BroadCastMessage.soap"); EventWrapper wrapper = new EventWrapper(); wrapper.LocalBroadCastEvent += new BroadCastEventHandler(BroadCastingMessage); watch.BroadCastEvent += new BroadCastEventHandler(wrapper.BroadCasting);

为什么这样做就可以了呢?也许画一幅图就很容易说明,可惜我的艺术天分实在很糟糕,我希望以后可以改进这一点。还是用文字来说明吧。

前面说,委托要装载client程序集。现在我们把远程对象委托装载的权利移交给EventWrapper。因为这个类对象是放在客户端的,所以它要装载client程序集丝毫没有问题。语句:

EventWrapper wrapper = new EventWrapper(); wrapper.LocalBroadCastEvent += new BroadCastEventHandler(BroadCastingMessage);

实现了这个功能。

  不过此时虽然订阅了事件,但事件还是客户端的,没有与服务端联系起来。而服务端的事件是放到远程对象中的,所以,还要订阅事件,这个任务由远程对象watch来完成。但此时它订阅的不再是BroadCastingMessage了,而是EventWrapper的触发事件方法BroadCasting。那么此时委托同样要装载程序集,但此时装载的就是BroadCasting所在的程序集了。由于装载发生的地点是在服务端。呵呵,高兴的是,BroadCasting所在的程序集正是公共程序集(前面已说过,EventWrapper应放到公共程序集Common.dll中),而公共程序集在服务端和客户端都已经部署了。自然就不会出现找不到程序集的问题了。

注意:EventWrapper因为要重写InitializeLifetimeService()方法,所以仍然要继承MarshalByRefObject类。

现在再来运行程序。首先运行服务端;然后运行客户端,OK,客户端窗体出现了:

/uploads/allimg/200612/1G6445418_0.gif

然后我们在服务端单击“BroadCast”按钮,发送广播消息:

/uploads/allimg/200612/1G640R02_0.gif

单击“Send”发送,再来看看客户端,会是怎样?Fine,I got it!

/uploads/allimg/200612/1G6414433_0.gif

怎么样,很酷吧!你也可以同时打开多个客户端,它们都将收到这个广播信息。如果你觉得这个广播声音太吵,那就请你在客户端取消广播吧。在Cancle按钮中:

private void btnCancle_Click(object sender, System.EventArgs e) { watch.BroadCastEvent -= new BroadCastEventHandler(wrapper.BroadCasting); MessageBox.Show("取消订阅广播成功!"); }

当然这个时候wrapper对象应该被申明为private对象了:
private EventWrapper wrapper = null;

/uploads/allimg/200612/1G6443064_0.gif

取消后,你试着再广播一下,恭喜你,你不会听到噪音了!

三、 客户端订阅客户端事件

  有了前面的基础,再来看客户端订阅客户端事件,就简单多了。而本文写到这里,我也很累了,你也被我啰嗦得不耐烦了。你心里在喊,“饶了我吧!”其实,我又何尝不是如此。所以我只提供一个思路,有兴趣的朋友,可以自己写一个程序。

  其实方法很简单,和第二种情况类似。发送信息的客户端,只需要获得远程对象后,发送消息就可以了。而接收信息的客户端,负责订阅该事件。由于事件都是放到远程对象中,因此订阅的方法和第二种情况没有什么区别!

  特殊的情况是,我们可以用第三种情况来代替第二种。只要你把发送信息的客户端放到服务端就可以了。当然需要做一些额外的工作,有兴趣的朋友可以去实现一下。在我的示例程序中,已经用这种方法模拟实现了服务端的广播,大家可以去看看。

四、 一点补充

我在前面的事件处理中,使用的都是默认的EventArgs。如果要定义自己的EventArgs,就不相同了。因为该信息是传值序列化,因此必须加上[Serializable],且必须放到公共程序集中,部署到服务端和客户端。例如:

[Serializable] public class BroadcastEventArgs:EventArgs { private string msg = null; public BroadcastEventArgs(string message) { msg = message; } public string Message { get {return msg;} } }

五、持续改进(经Beta的提醒,我改进了我的程序,并对文章进行了修改 2004年12月13日)

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wjypdf.html