多系统通讯-DotNetMQ

很久都没有写博客了,从15年4月份一直忙到现在,我才有时间去做梳理和总结,因为我提离职了,感觉整个世界突然变得不一样,随着而来的就是心情的放松,写一篇文章也是对过去一年多工作的梳理,加深印象 积累和沉淀。

因为从事的公司是建筑行业的公司,产品也是基于建筑管理体系,整体的项目包含了web端、客户端、服务端,以及因为产品功能需要的一些工具类的软件。在这种多系统的体系结构之下,我们需要进行多个系统之间的实时通讯,其实做到实时通讯的方式有很多种

1.sql server的Server_borker    数据变更通知,是基于sql server数据库的,表中的数据变更会通知到监听的那端,但是觉得考虑到通讯比较频繁,通讯端比较多,这种方式很容易造成代码上和程序上的混乱,不做考虑。

2.wcf的消息广播   相比第一种,这个对于这种多系统通讯更加不具备优势。这种在服务端进行操作,客户端通过注册来监听服务端处理的进度很明显不适合两个或者多个客户端之间的通信,我们的系统可不仅仅限于客户端服务端这么简单,不做考虑。

3..NetMQ 就是本章中要介绍的解决多系统通讯问题的杀手锏了。这个其实在最开始是我们同事去下载研究的,在之后经过一些包装可以很方便的去使用,接下来我们去一起了解一下。

下载地址:http://www.codeproject.com/Articles/193611/DotNetMQ-A-Complete-Message-Queue-System-for-NET

简单的画个图可以更加方便的去了解这个结构

通过这个图我们可以看到,在多个客户端通讯之前需要先开启服务,然后通过唯一性的token我们就可以做到客户端之间的信息通讯。

下载下来的应该是一个服务的启动程序和一个管理端,经过包装和更改更加方便使用一些:

两个服务

1..NETMQ本身的服务

2.添加令牌的服务,开放成对外的wcf接口,可以通过接口取添加令牌。

关于服务配置其实修改后只需要服务端口就行了,连接通过地址和端口号就可以连接。

 

 

最后就是令牌了,令牌就是客户端之间通讯的一个token,就是一个唯一的识别信息,就跟qq一样,给妹子发信息总要知道人家的qq号吧,token其实也可以这么理解。

客户端上线之后就客户端连接就是1。

通过上述的描述我想基本都对这个有一个印象了,通过这些印象我们可以想象到他的应用场景,比如去做一个聊天工具,做上传下载的进度提示,等等。

了解了应用场景我们就应该去想想我们怎么样才能简单而又方便的把它应用在我们的项目中,可以解决我们产品和项目中的实际问题。

 

服务端:

图中可以看到,我们下载下来的.NETMQ在服务端只需要引用这三个库就可以了,

MQServer就是我们针对实际项目应用做的一些修改,将服务开启、停止、令牌的添加删除以及管理都在这里做了包装,只需要去引用就可以了。

/// <summary>/// 消息中心服务器端管理类/// </summary>public class MQService{#region 单例private static MQService _instance;/// <summary>/// 单例/// </summary>public static MQService Instance{get{if (_instance == null){_instance = new MQService();}return _instance;}}#endregion#region 字段MDSServer server;MDSController controller;#endregion#region 属性/// <summary>/// 服务是否处于开启状态/// </summary>public bool IsOpened { get; set; }#endregion#region 构造方法public MQService(){server = new MDSServer();}#endregion
#region 开启服务/// <summary>/// 开启服务/// </summary>public void Start(){try{server.Start();IsOpened = true;controller = new MDS.Management.MDSController(AppConfig.Config.MessageServiceIP, AppConfig.Config.MessageServicePort);controller.Connect();}catch (Exception ex){throw ex;}}#endregion#region 关闭服务/// <summary>/// 关闭服务/// </summary>public void Stop(){try{if (IsOpened){server.Stop(true);IsOpened = false;controller.Disconnect();}}catch (Exception ex){throw ex;}}#endregion#region 添加令牌public bool AddToken(string token){try{controller.SendMessage(new AddNewApplicationMessage{ApplicationName = token});return true;}catch{return false;}}#endregion
#region 删除令牌public void RemoveToken(string token){var message = controller.SendMessageAndGetResponse(new RemoveApplicationMessage{ApplicationName = token});}#endregion
#region 获取令牌列表public ObservableCollection<TokenClass> GetTokenList(){ObservableCollection<TokenClass> result = new ObservableCollection<TokenClass>();//Send a message to MDS server to get list of client applications, get response and fill data grid.var message = controller.SendMessageAndGetResponse(new GetApplicationListMessage());if (message.MessageTypeId != ControlMessageFactory.MessageTypeIdGetApplicationListResponseMessage){throw new MDSException("Response message to GetApplicationListMessage must be a GetApplicationListResponseMessage");}var applicationListMessage = message as GetApplicationListResponseMessage;if (applicationListMessage == null){throw new MDSException("Incorrect message type. MessageTypeId = " + message.MessageTypeId + ", but Type of object: " + message.GetType().Name);}MDS.Communication.Messages.ControllerMessages.GetApplicationListResponseMessage.ClientApplicationInfo[] applications = applicationListMessage.ClientApplications;
foreach (var application in applications){TokenClass tc = new TokenClass();tc.TokenName = application.Name;tc.TokenConnect = application.CommunicatorCount;result.Add(tc);}return result;}#endregion}
View Code

服务端简单的使用就是这些,详细的介绍以及内部原理网上很多,这里就不介绍了。

 

客户端:

关于客户端呢,为了便于更方便的使用我写一个简单的demo去演示一下。

图中红框的部分其实就是MDSCommonLib这个库,下面几个类就是对外的事件和方法的包装,我们可以看一下代码:

public class MQMessage{CommunicationClient client;public readonly static MQMessage Instance = new MQMessage();public MQMessage(){//FileTransfer.BLL.XmlReader.ReadXmlInfo();client = new CommunicationClient();client.OnMessageReceived += client_OnMessageReceived;client.OnResponseMessageReceived += client_OnResponseMessageReceived;}/// <summary>/// 接收消息事件/// </summary>public event EventHandler OnMessageReceived;/// <summary>/// 接收消息回执事件/// </summary>public event EventHandler OnResponseMessageReceived;/// <summary>/// 接收消息事件/// </summary>/// <param name="sender"></param>/// <param name="e"></param>void client_OnResponseMessageReceived(object sender, MessageReceiveEventArgs e){if (OnResponseMessageReceived != null){OnResponseMessageReceived(sender, e);}}/// <summary>/// 接收消息回执事件/// </summary>/// <param name="sender"></param>/// <param name="e"></param>void client_OnMessageReceived(object sender, MessageReceiveEventArgs e){if (OnMessageReceived != null){OnMessageReceived(sender, e);}}/// <summary>/// 发送消息/// </summary>/// <param name="messageContent"></param>public void SendMessage(string messageContent, string tokenName){client.SendMessage(messageContent, tokenName);}/// <summary>/// 开启服务/// </summary>public void Start(string tokenName){client.StartConnection("127.0.0.1", 10905, tokenName);}/// <summary>/// 关闭服务/// </summary>public void Stop(){client.StopConnection();}}
View Code

这是最外层的包装,通过这些就可以去调用

MQClientLib.MQMessage.Instance.Start("User_Sean");

 

客户端开启连接的方式仅仅这样就可以了,通过这行表示:User_Sean上线了。

这样我们在服务端就可以看到User_Sean的连接:

 

 

呐,这是一个客户端,如果是多个客户端连接上了呢? 我们就可以通过

 

/// <summary>/// 发送消息/// </summary>/// <param name="messageContent"></param>public void SendMessage(string messageContent, string tokenName){client.SendMessage(messageContent, tokenName);}

调用这行代码去向其它客户端发送信息,其它客户端接收到信息的时候也会触发这边的回执事件。

/// <summary>/// 接收消息回执事件/// </summary>public event EventHandler OnResponseMessageReceived;

通过注册这个事件,在对方接收到你发送的消息的时候,可以触发这个事件。

 

/// <summary>
/// 接收消息事件
/// </summary>
public event EventHandler OnMessageReceived;

 

这个是用来接收别人给你发送的信息的,信息通过这个时间的sender传递过来。

 

使用暂时就这些,因为代码是加密的,所以只能以后去重新做一下然后给各位提供下载地址了。

当然,关于mq的使用dotNetMQ只是其中一项,今天介绍的也只是通讯,之后下一篇博客会介绍相关的msmq、queue等等,后面精彩继续~~~~~ 

转载于:https://www.cnblogs.com/BeiJing-Net-DaiDai/p/6030941.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/260207.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

九大现代病!中枪了吗?

现代人在享受现代化的生活和工作方式带来的便捷之时&#xff0c;也为此付出了不小的代价&#xff0c;下面列出的九大现代病就是典型的例子&#xff0c;看看你有没有中枪。 办公臀 常坐办公室&#xff0c;如果你发现屁股越坐越大&#xff0c;大腿越坐越粗&#xff0c;你可能有了…

Java学习笔记(4)——枚举类型

1.在类别&#xff08;Class&#xff09;或接口&#xff08;Interface&#xff09;中宣告常数加以管理&#xff0c;这只是让您存取与管理常数方便而已&#xff0c;来看看这个例子&#xff1a; public void someMethod() {....doOp(OpConstants.TURN_RIGHT);.... } public void d…

驱动提取软件_深入分析施耐德工控软件代码执行漏洞

更多全球网络安全资讯尽在邑安全简介在本文中&#xff0c;我们将为读者详细介绍Claroty Research团队的Amir Preminger和Sharon Brizinov是如何组合利用两个漏洞&#xff0c;来触发施耐德工控软件EcoStruxure Operator Terminal Expert的代码执行漏洞&#xff0c;从而在首届举办…

ubuntu 网卡突然无法连接

今天要用到VM BT的Namp扫描服务器端口&#xff0c;发现桥接后无法使用。ifconfig 只看到 lo地址&#xff0c;看不到以太网网卡地址使用lspci 查看是否安装了以太网网卡驱动lscpi | grep Ethernet02:01.0 Ethernet controller: Advanced Micro Devices [AMD] 79c970 [PCnet32 LA…

atitit.表单验证 的dsl 本质跟 easyui ligerui比较

atitit.表单验证的dsl 本质跟 easyui ligerui比较 1. DSL 声明验证 1 2. 自定义规则 1 3. 正则表达式验证,可以扩展实现 2 4. 犯错误消息提示,generic canBeEmpty is good 3 5. Prevent the form to submit when invalid 3 6. 为空则不验证&#xff0c;不为空则验证&#xff0…

StartActivityForResult

StartActivity 用startActivityForResult(intent, requestcode);启动子功能模块activity onActivityResult(int requestCode, int resultCode, Intent data)对子activity返回进行判断处理 public class StartActivity extends Activity implements OnClickListener {private Bu…

micropython 串口写文件_MicroPython通过2G模块串口收发短信

集成2G通信、定位模组&#xff0c;赋予物联网特性。本例使用M6220&#xff0c;它是一款基于eSIM技术的2G模组&#xff0c;支持GSM/GPRS&#xff0c;提供GPS北斗双模定位功能&#xff0c;并具备一定的数据处理能力&#xff0c;其2G工作频段有GSM850、GSM900、DCS1800和PCS1900&a…

洛谷P1130 红牌

题目描述 某地临时居民想获得长期居住权就必须申请拿到红牌。获得红牌的过程是相当复杂 &#xff0c;一共包括N个步骤。每一步骤都由政府的某个工作人员负责检查你所提交的材料是否符合条件。为了加快进程&#xff0c;每一步政府都派了M个工作人员来检查材料。不幸的是&#xf…

GPS坐标换算

30.8872 》——>300.8872*60 53.232 ——>530.232*60 13.9230: 53 13.92"30: 53 13.92"》3053/6013.92/360030.887199同经度两点之间距离dla30.887m * [差值/(1/3600)] 30.887m * 差值 *3600 111193.2m * 差值 同纬度两点之间距离dlo30.887m * [差值/(1…

企业级应用框架(五)IOC容器在框架中的应用

前言 在上一篇我大致的介绍了这个系列所涉及到的知识点&#xff0c;在本篇我打算把IOC这一块单独提取出来讲&#xff0c;因为IOC容器在解除框架层与层之间的耦合有着不可磨灭的作用。当然在本系列前面的三篇中我也提供了一种基于反射的解耦方式&#xff0c;但是始终不是很优雅&…

后端开发需要学什么_都2020年了,还在纠结学什么语言?| 后端篇

几个礼拜前&#xff0c;一个学弟问我&#xff1a;“Ray&#xff0c;我打算之后要找工作了&#xff0c;不过现在自己没有特别深入的语言&#xff0c;最近想找一门好好学一下&#xff0c;你觉得学什么语言好呀&#xff1f;”我表示&#xff1a;“这个要看你求职方向、个人喜好、市…

python扫描ip的端口打开情况

我们的韩国bss系统上线之后&#xff0c;要求对主机的端口、资源使用进行统计&#xff0c;端口每个主机去看&#xff0c;太费劲了&#xff0c;所以&#xff0c;就写了这样一个小程序&#xff0c;不是很完美但是&#xff0c;可以用啊&#xff01;哈哈哈&#xff0c;别喷&#xff…

flash java 通信,Flash到JavaScript的通信实例

从HTML可以发送数据到Flash,反过来也可以. 这个例子演示了如何应用Flash的Fscommand来发送数据到Javascript.简要步骤:Flash中新建一个文件,保存为flash_to_javascript.fla创建一个文本域,设置成输入文本(Input Text),选择"border"以便我们能看到他,指定他的变量为in…

10个非常有用的CSS hack和技术

转自&#xff1a;http://www.qianduan.net/10-useful-css-hacks-and-technique.html 1 – 跨浏览器的inline-block <style>li {width: 200px;min-height: 250px;border: 1px solid #000;display: -moz-inline-stack;display: inline-block;margin: 5px;zoom: 1;*display:…

Java的递归算法

递归算法设计的基本思想是&#xff1a;对于一个复杂的问题&#xff0c;把原问题分解为若干个相对简单类同的子问题&#xff0c;继续下去直到子问题简单到可以直接求解&#xff0c;也就是说到了递推的出口&#xff0c;这样原问题就有递推得解。 关键要抓住的是&#xff1a; &…

python list遍历定位元素_python for循环,第二遍定位不到元素?

ycyzharry: 也不行&#xff0c;我的代码import unittestimport timeimport xlrdfrom selenium import webdriverimport seleniumdef open_excel(filefile.xls):try:data xlrd.open_workbook(file)return dataexcept Exception as e:print(str(e))def excel_table_byindex(file…

发现Java程序中的Bug

昨天在CSDN上阅读 "Java中十个常见的违规编码"这篇文章时&#xff0c;无意中找到了3个 "发现Java程序中的Bug"工具。 文章地址&#xff1a;http://www.csdn.net/article/2012-09-11/2809829-common-code-violations-in-java其中&#xff0c; FindBugs™ - …

原生php登录注册,原生php登陆注册

本以为一个登陆注册功能十来分钟就写好了&#xff0c;没想到thinkPHP用久了&#xff0c;原生的php不会写了最开始我直接写了类和方法&#xff0c;在前台传递参数给类的login方法(action"index.php/login"),尝试几次发现无法访问&#xff0c;这才意识到&#xff0c;这…

SpringMVC REST 风格静态资源访问配置

1 在web.xml中使用默认servlet处理静态资源&#xff0c;缺点是如果静态资源过多&#xff0c;则配置量会比较大&#xff0c;一旦有遗漏&#xff0c;则会造成资源无法正常显示或404错误。 <!-- 静态资源访问控制 --><servlet-mapping><servlet-name>default<…

生成对象

var c[name,age,city]; var d[xiaogang,12,anhui]; var a{}; for(var i0;i<3;i){a[c[i]]d[i]; } console.log(a); //返回 {name: "xiaogang", age: "12", city: "anhui"} 转载于:https://www.cnblogs.com/xiaozhumaopao/p/6046823.html