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

private void ServerForm_Load(object sender, System.EventArgs e) { HttpChannel channel = new HttpChannel(8080); ChannelServices.RegisterChannel(channel); RemotingConfiguration.RegisterWellKnownServiceType( typeof(FaxBusiness),"FaxBusiness.soap",WellKnownObjectMode.Singleton); FaxBusiness.FaxSendedEvent += new FaxEventHandler(OnFaxSended); }

  我们采用的是SingleTon模式,注册了一个远程对象。注意看,这段代码和一般的Remoting服务端有什么区别?对了,它多了一行注册事件的代码:

FaxBusiness.FaxSendedEvent += new FaxEventHandler(OnFaxSended);

这行代码,就好比我们服务端的传真机,一直切换为“自动”模式。它会一直监听着来自客户端的传真信息,一旦传真信息从客户端发过来了,则响应事件方法,即OnFaxSended方法:

public void OnFaxSended(string fax) { txtFax.Text += fax; txtFax.Text += System.Environment.NewLine; }

这个方法很简单,就是把客户端发过来的Fax显示到txtFax文本框控件上。

而客户端呢?仍然是一个Windows应用程序。代码非常简单,首先为了简便其见,我们仍然让它在装载窗体的时候,激活远程对象:

private void ClientForm_Load(object sender, System.EventArgs e) { HttpChannel channel = new HttpChannel(0); ChannelServices.RegisterChannel(channel); faxBus = (IFaxBusiness)Activator.GetObject(typeof(IFaxBusiness), "http://localhost:8080/FaxBusiness.soap"); }

呵呵,可以说客户端激活对象的方法和普通的Remoting客户端应用程序没有什么不同。该写传真了!我们在窗体上放一个文本框对象,改其Multiline属性为true。再放一个按钮,负责发送传真:

private void btnSend_Click(object sender, System.EventArgs e) { if (txtFax.Text != String.Empty) { string fax = "来自" + GetIpAddress() + "客户端的传真:" + System.Environment.NewLine; fax += txtFax.Text; faxBus.SendFax(fax); } else { MessageBox.Show("请输入传真内容!"); } } private string GetIpAddress() { IPHostEntry ipHE = Dns.GetHostByName(Dns.GetHostName()); return ipHE.AddressList[0].ToString(); }

  在这个按钮单击事件中,只需要调用远程对象faxBus的SendFax()方法就OK了,非常简单。可是慢着,为什么你的代码有这么多行啊?其实,没有什么奇怪的,我只是想到发传真的客户可能会很多。为了避免服务端人员犯糊涂,搞不清楚是谁发的,所以要求在传真上加上各自的签名,也就是客户端的IP地址了。既然要获得计算机的IP地址,请一定要记得加上对DNS的命名空间引用:
using System.Net;

  因为我们严格按照分布式处理程序的部署方式,所以在客户端只需要添加公共程序集(Common.dll)的引用就可以了。而在服务端呢,则必须添加公共程序集和远程对象程序集两者的引用。

OK,程序完成,我们来看看这个简陋的传真机:
客户端:

/uploads/allimg/200612/1G6439112_0.gif

嘿嘿,做梦都想放假啊。好的,传真写好了,发送吧!再看看服务端,great,老板已经收到我的请假条传真了!

/uploads/allimg/200612/1G63c354_0.gif

二、 客户端订阅服务端事件

  嘿嘿,吃甘蔗要先吃甜的一段,做事情我也喜欢先做容易的。现在,好日子过去了,该吃点苦头了。我们先回忆一下刚才的实现方法,再来思考怎么实现客户端订阅服务端事件?

  在前一节,事件被放到远程对象中,客户端激活对象后,就可以发送消息了。而在服务端,只需要订阅该事件就可以。现在思路应该反过来,由客户端订阅事件,服务端发送消息。就这么简单吗?先不要高兴得太早。我们想一想,发送消息的任务是谁来完成的?是远程对象。而远程对象是什么时候创建的呢?我们仔细思考Remoting的几种激活方式,不管是服务端激活,还是客户端激活,他们的工作原理都是:客户端决定了服务器创建远程对象实例的时机,例如调用了远程对象的方法。而服务端所作的工作则是注册该远程对象。

回忆这三种激活方式在服务端的代码:

SingleCall激活方式:

RemotingConfiguration.RegisterWellKnownServiceType( typeof(BroadCastObj),"BroadCastMessage.soap", WellKnownObjectMode.Singlecall);

SingleTon激活方式:

RemotingConfiguration.RegisterWellKnownServiceType( typeof(BroadCastObj),"BroadCastMessage.soap", WellKnownObjectMode.Singleton);

客户端激活方式:

RemotingConfiguration.ApplicationName = “BroadCastMessage.soap” RemotingConfiguration.RegisterActivatedServiceType(typeof(BroadCastObj));

请注意Register这个词语,它表达的含义就是注册。也就是说,在服务端并没有显示的创建远程对象实例。没有该实例,又如何广播消息呢?

或许有人会想,在注册远程对象之后,显式实例该对象不就可以了吗?也就是说,在注册后加上这一段代码:

BroadCastObj obj = new BroadCastObj();

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

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