没有合适的资源?快使用搜索试试~ 我知道了~
首页分布式 c# Remoting初学
资源详情
资源评论
资源推荐
前言:在 Remoting 中处理事件其实并不复杂,但其中有些技巧需要你去挖掘出来。正是
这些技巧,仿佛森严的壁垒,让许多人望而生畏,或者是不知所谓,最后放弃了事件在
Remoting 的使用。关于这个主题,在网上也有很多讨论,相关的技术文章也不少,遗憾
的是,很多文章概述的都不太全面。我在研究 Remoting 的时候,也对事件处理发生了兴
趣。经过参考相关的书籍、文档,并经过反复的试验,深信自己能够把这个问题阐述清楚
了。
本文对于 Remoting 和事件的基础知识不再介绍,有兴趣的可以看我的系列文章,或查阅
相关的技术文档。
本文示例代码下载:
Remoting
事件 ( 客户端发传真 )
Remoting
事件 ( 服务端广播 )
Remoting
事件 ( 服务端广播改进 )
应用 Remoting 技术的分布式处理程序,通常包括三部分:远程对象、服务端、客户端。
因此从事件的方向上看,就应该有三种形式:
1、服务端订阅客户端事件
2、客户端订阅服务端事件
3、客户端订阅客户端事件
服务端订阅客户端事件,即由客户端发送消息,服务端捕捉该消息,然后响应该事件,相
当于下级向上级发传真。反过来,客户端订阅服务端事件,则是由服务端发送消息,此时,
所有客户端均捕获该消息,激发事件,相当于是一个系统广播。而客户端订阅客户端事件
呢?就类似于聊天了。由某个客户端发出消息,其他客户端捕获该消息,激发事件。可惜
的是,我并没有找到私聊的解决办法。当客户端发出消息后,只要订阅了该事件的,都会
获得该信息。
然而不管是哪一种方式,究其实质,真正包含事件的还是远程对象。原理很简单,我们想
一想,在 Remoting 中,客户端和服务端传递的内容是什么呢?毋庸置疑,是远程对象。
因此,我们传递的事件消息,自然是被远程对象所包裹。这就像 EMS 快递,远程对象是运
送信件的汽车,而事件消息就是汽车所装载的信件。至于事件传递的方向,只是发送者和
订阅者的角色发生了改变而已。
一、ñ服务端订阅客户端事件
服务端订阅客户端事件,相对比较简单。我们就以发传真为例。首先,我们必须具备传真
机和要传真的文件,这就好比我们的远程对象。而且这个传真机上必须具备“发送”的操作
按钮。这就好比是远程对象中的一个委托。当客户发送传真时,就需要在客户端上激活一
个发送消息的方法,这就好比我们按了“发送”按钮。消息发送到服务端后,触发事件,这
个事件正是服务端订阅的。服务端获得该事件消息后,再处理相关业务。这就好比接收传
真的人员,当传真收到后,会听到接通的声音,此时选择“接收”后,该消息就被捕获了。
现在,我们就来模拟这个流程。首先定义远程对象,这个对象处理的应该是一个发送传真
的业务:
首先是远程对象的公共接口(Common.dll):
public delegate void FaxEventHandler(string fax);
public interface IFaxBusiness
{
&&& void SendFax(string fax);
}
注意,在公共接口程序集中,定义了一个公共委托。
然后我们定义具体处理传真业务的远程对象类(FaxBusiness.dll),在这个类中,先要
添加对公共接口程序集的引用:
public class FaxBusiness:MarshalByRefObject,IFaxBusiness
{&
&public static event FaxEventHandler FaxSendedEvent;
&#region
&public void SendFax(string fax)
&{
&&if (FaxSendedEvent != null)
&&{
&&&FaxSendedEvent(fax);
&&}
&}
&#endregion
&public override object InitializeLifetimeService()
&{
&&return null;
&}
}
这个远程对象中,事件的类型就是我们在公共程序集 Common.dll 中定义的委托类型。
SendFax 实现了接口 IFaxBusiness 中的方法。这个方法的签名和定义的委托一致,它调
用了事件 FaxSendedEvent。
特殊的地方是我们定义的远程对象最好是重写 MarshalByRefObject 类的
InitializeLifetimeService()方法。返回 null 值表明这个远程对象的生命周期为无限大。
为什么要重写该方法呢?道理不言自明,如果生命周期不进行限制的话,一旦远程对象的
生命周期结束,事件就无法激活了。
接下来就是分别实现客户端和服务端了。服务端是一个 Windows 应用程序,界面如下:
&
我们在加载窗体的时候,注册通道和远程对象:
private void ServerForm_Load(object sender, System.EventArgs e)
{
&HttpChannel channel = new HttpChannel(8080);
&ChannelServices.RegisterChannel(channel);
&RemotingCon9guration.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,程序完成,我们来看看这个简陋的传真机:
客户端:
&
嘿嘿,做梦都想放假啊。好的,传真写好了,发送吧!再看看服务端,great,老板已经
收到我的请假条传真了!
&
二、ñ客户端订阅服务端事件
嘿嘿,吃甘蔗要先吃甜的一段,做事情我也喜欢先做容易的。现在,好日子过去了,该吃
点苦头了。我们先回忆一下刚才的实现方法,再来思考怎么实现客户端订阅服务端事件?
在前一节,事件被放到远程对象中,客户端激活对象后,就可以发送消息了。而在服务端,
只需要订阅该事件就可以。现在思路应该反过来,由客户端订阅事件,服务端发送消息。
就这么简单吗?先不要高兴得太早。我们想一想,发送消息的任务是谁来完成的?是远程
剩余20页未读,继续阅读
two2xiao
- 粉丝: 2
- 资源: 35
上传资源 快速赚钱
- 我的内容管理 收起
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
会员权益专享
最新资源
- stc12c5a60s2 例程
- Android通过全局变量传递数据
- c++校园超市商品信息管理系统课程设计说明书(含源代码) (2).pdf
- 建筑供配电系统相关课件.pptx
- 企业管理规章制度及管理模式.doc
- vb打开摄像头.doc
- 云计算-可信计算中认证协议改进方案.pdf
- [详细完整版]单片机编程4.ppt
- c语言常用算法.pdf
- c++经典程序代码大全.pdf
- 单片机数字时钟资料.doc
- 11项目管理前沿1.0.pptx
- 基于ssm的“魅力”繁峙宣传网站的设计与实现论文.doc
- 智慧交通综合解决方案.pptx
- 建筑防潮设计-PowerPointPresentati.pptx
- SPC统计过程控制程序.pptx
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
评论1