多系统通讯-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;你可能有了…

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

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

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…

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

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

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

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

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; &…

发现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™ - …

shiro前后端分离_为什么要前后端分离?前后端分离的优点是什么?

随着互联网的高速发展以及IT开发技术的升级&#xff0c;前后端分离已成为互联网项目开发的业界标准使用方式。在实际工作中&#xff0c;前后端的接口联调对接工作量占HTML5大前端人员日常工作的30%-50%&#xff0c;甚至会更高。接下来千锋小编分享的广州HTML5大前端学习就给大家…

hdu--1075--字典树||map

做这题的时候 我完全没想到 字典树 就直接用map来做了 - 我是有 多不 敏感啊~~ 然后去 discuss 一看 很多都是说 字典树的问题.... 字典树 给我感觉 它的各个操作的意思都很清晰明了 直接手写 不那么容易啊。。 晚些 时候 试下来写------用map写是真心方便 只要注意下那么\n的吸…

php的类装载的步骤,设计PHP自动类装载功能

在使用面向对象方法做PHP开发时&#xff0c;可能会经常使用到各个路径中的类文件&#xff0c;这就需要大量的 include 或 require&#xff0c;而 PHP 提供了一个比较快捷的方式&#xff0c;就是利用函数 __autoload 可以编程实现动态的类装载功能&#xff0c;这样就不需要手动的…

网站首页幻灯片

Js页面: View Code /** * 大眼睛广告轮播 */ var indexEye {autoTime: 0,init: function () {var eyeObj $("#dyj_pics a:eq(0) img:eq(0)");eyeObj.attr("src", eyeObj.attr("data-imgSrc"));eyeObj.load(function () {indexEye.autoTime se…

Qt之QAbstractItemView视图项拖拽(二)

一、需求说明 上一篇文章Qt之QAbstractItemView视图项拖拽(一)讲述了实现QAbstractItemView视图项拖拽的一种方式&#xff0c;是基于QDrag实现的&#xff0c;这个类是qt自己封装好了的&#xff0c;所以可定制性也就没有了那么强&#xff0c;最明显的是&#xff0c;这个类在执…

电脑控制苹果手机_必备神器,电脑控制手机

序一款电脑端的神器&#xff0c;它可以任意的操纵你的手机。****QtScrcpy可以通过USB(或通过TCP/IP)连接Android设备&#xff0c;并进行显示和控制。不需要root权限。单个应用程序最多支持16个安卓设备同时连接。同时支持GNU/Linux&#xff0c;Windows和MacOS三大主流桌面平台。…

生活大爆炸版石头剪刀布

题目描述 Description石头剪刀布是常见的猜拳游戏&#xff1a;石头胜剪刀&#xff0c;剪刀胜布&#xff0c;布胜石头。如果两个人出拳一样&#xff0c;则不分胜负。在《生活大爆炸》第二季第8集中出现了一种石头剪刀布的升级版游戏。升级版游戏在传统的石头剪刀布游戏的基础上&…

jquery事件 on(),live(),delegate(),blind()

jQuery推出on()的目的有2个&#xff0c;一是为了统一接口&#xff0c;二是为了提高性能&#xff0c; 所以从现在开始用on()替换bind(), live(), delegate吧。 尤其是不要再用live()了&#xff0c;因为它已经处于不推荐使用列表了[1.7已经被删除]。 如果只绑定一次事件&#xff…

用python庆祝生日_生日到底该过阴历还是阳历好呢?不是迷信,都怪我们大意!...

过生日到底该过阴历还是阳历&#xff1f;答案说出来你可能都不信在我们国家&#xff0c;过生日有两种不同的方式&#xff0c;因为有两种不同的日子的计算方式&#xff0c;分为阴历和阳历。一般来说&#xff0c;在农村和一些比较落后的地方&#xff0c;人们习惯于用阴历来计算生…

WSS3.0自带数据库可以使用SQL 2005 Server Management Studio来管理

默认情况下&#xff0c;安装完WSS3.0后&#xff0c;会自动安装一个自带的SQL Server 2005 Embedded Edition数据库&#xff0c;但是此数据库却没有管理工具,不像安装SQL 2005其它版本会有管理工具。如果你要管理数据库&#xff0c;这时怎么办呢。经过俺试了一上午了&#xff0c…

CPU的高速缓存存储器知识整理

基于缓存的存储器层次结构 基于缓存的存储器层次结构行之有效&#xff0c;是因为较慢的存储设备比较快的存储设备更便宜&#xff0c;还因为程序往往展示局部性&#xff1a; 时间局部性&#xff1a;被引用过一次的存储器的位置很可能在不远的将来被再次引用。 空间局部性&#x…

uniapp光标自动定义到文本框_word技巧自动生成毕业论文目录

一篇word文档&#xff0c;内容有大的章&#xff0c;小的节。如何把章节抽出来生成目录&#xff1f;WORD →点击需要插入的地方 → 插入菜单 → 索引和目录 → 目录 → 确定。1 创建标题目录Word 一般是利用标题或者大纲级别来创建目录的。因此&#xff0c;在创建目录之前&#…