初探Remoting双向通信(四)
来源:互联网 发布:深圳优化工程塑料 编辑:程序博客网 时间:2024/05/16 12:00
之前已经从基本原理上实现了Remoting的双向通信。准备将其移植到我的项目中,不过为了成功移植,我还是需要再把以前的版本稍作修改才能放心的去做。项目中当一台机子中有工作人员进行了预警信息标记时(在地图上会有一个标志),其他机子需要同步更新。这就是说任何一个客户端进行标记时需要通知服务器,然后让服务器去广播标记。这一个小动作就需要双向通信一次。按照项目需求,我再次修改版本,这次只需要改一个函数:
修改服务器订阅事件函数如下:
void marshal_obj_SubscribeAtServer(string msg) { //跨线程调用 textBox2.Invoke(new Action<string>(str => { textBox2.AppendText(str); }), msg); //订阅函数不在主线程,需另起线程触发广播方法 Thread th = new Thread(new ThreadStart(() => { marshal_obj.TriggerAtServer("服务器--" + this.ServerIP() + System.Environment.NewLine + "我是服务器,我发现一个客户端有标记行为,我要让你们全部都标记!" + System.Environment.NewLine); })); th.Start(); }
然后开启一个服务器3个客户端,让其中一个客户端发起标记事件,效果如下:
有了这个,我更加肯定的去修改自己的项目了。经过一整天的大改,我把项目调试通了,开了1个服务器,2个客户端,分别设置了断点,虽然其中事件订阅处有很多逻辑处理,并不像上面DEMO那样只发送一段文字,但是每一个断点都可以运行到,那就说明整体上是通了。删除断点后,很高兴的看一下新的效果时,却让我大失所望:
当一个客户端进行标记时,第二个客户端确实也收到了信息,但是第一个客户端界面已经卡死,很久才能恢复,甚至当机。这就让我想起了上面这个Demo运行的效果时的现象了。上面的三个客户端收到信息并不是同时的,而是依次的。况且,所谓的广播发送,其实利用的就是多播委托,并不像Socket那样是3个tcpclient来进行通信的。服务器端利用Marshal得到的对象和3个客户端激活得到的对象是同一个引用(SingleTon方式),所以客户端订阅的事件都是在服务器同一个对象上的委托列表里。当直接调用委托的时候,调用的是委托的Invoke方法,该方法会在执行的时候阻塞当前线程,直到委托列表执行完才会将控制权转回来。这样一来,委托的超时必然会引起界面的假死(当有更多逻辑处理在事件订阅函数里时更糟糕)。呢有什么办法呢,查找了资料,看了"张子阳"的委托与事件觉得很不错,仔细拜读了好几遍。原来委托执行的列表是可以获取的,而且可以认为的去遍历,这么一来就可以解决许多问题:比如有一个客户端发生了异常,为了不影响其他的客户端,可以遍历的时候try/catch掉;再比如遍历的时候为了不阻塞客户端线程,可以每次另起一个线程(这里就用到了BeginInvoke,它就相当于另起线程执行委托,只不过它用的是线程池)。好了,再次修改以下服务器的订阅函数,如下:
void marshal_obj_SubscribeAtServer(string msg) { //跨线程调用 textBox2.Invoke(new Action<string>(str => { textBox2.AppendText(str); }), msg); //遍历委托列表 Delegate[] del_list = marshal_obj.GetServerEventList(); foreach (Delegate del in del_list) { MyDelegate d = (MyDelegate)del; d.BeginInvoke( "服务器--" + this.ServerIP() + System.Environment.NewLine + "我是服务器,我发现一个客户端有标记行为,我要让你们全部都标记!" + System.Environment.NewLine, null, null); } }
其中GetServerEventList()这个方法是在远程对象里新加的:
//获取委托列表 public Delegate[] GetServerEventList() { return this.SubscribeAtClient.GetInvocationList(); }
这次,我开了很多客户端,接收到信息几乎是同步的(至少肉眼分辨不出来),并且将项目也进行了改进,也有了重大突破。感谢网上许多乐于分享的大牛们,Remoting的学习暂时告一段落,还有其他事情要做,前方的路已然坎坷,而我却乐此不疲。。。。。
(注:上面的Demo在此处下载http://download.csdn.net/detail/kkkkkxiaofei/5650187)
- 初探Remoting双向通信(四)
- 初探remoting双向通信(一)
- 初探Remoting双向通信(二)
- 初探Remoting双向通信(三)
- [原创].NET Remoting: 如何通过Remoting实现双向通信(Bidirectional Communication)
- 如何通过Remoting实现双向通信
- 如何通过Remoting实现双向通信
- 企业开发基础设施--事件通知服务(Remoting双向通信)
- tolua++初探(四)
- Oracle初探(四)
- 初探UiAutomator(四)
- 异常初探(四)
- 多线程初探(四)
- 集合初探(四)
- java 初探(四)
- delphi prism 如何通过.net Remoting实现双向通信
- .Net Remoting的双向通信和Windows Service的宿主服务
- .Net Remoting的双向通信和Windows Service的宿主服务
- 张东:大数据时代挑战与解决之道
- jquery插件案例
- 发送短信的方法
- log4j 格式详解
- OK6410驱动学习之first_drv
- 初探Remoting双向通信(四)
- 常用正则表达式
- android系统源码编译问题
- Oracle Database 12c已经可以下载
- 文件服务器NFS配置详解
- 哈佛图书馆的二十条训言
- 挑战你的想象力 半年IT奇葩产品小结
- [C++]实现委托模型
- android访问远程数据库,C#服务器,android客户端