多系统通讯-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
}
服务端简单的使用就是这些,详细的介绍以及内部原理网上很多,这里就不介绍了。
客户端:
关于客户端呢,为了便于更方便的使用我写一个简单的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", , tokenName);
} /// <summary>
/// 关闭服务
/// </summary>
public void Stop()
{
client.StopConnection();
}
}
这是最外层的包装,通过这些就可以去调用
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等等,后面精彩继续~~~~~
多系统通讯-DotNetMQ的更多相关文章
- 【翻译】DotNetMQ: 一个.NET版完整的消息队列系统
在一个大型的分布式系统中,消息队列是不可缺少的中间件,能很好的解决异步消息.应用解耦.均衡并发等问题.在.net中,偶然发现一个效率不错.安全可靠.功能齐全的消息组件,忍不住翻译过来,供大家快速预览. ...
- Windows Azure Service Bus Topics实现系统松散耦合
前言 Windows Azure中的服务总线(Service Bus)提供了多种功能, 包括队列(Queue), 主题(Topic),中继(Relay),和通知中心(Notification Hub) ...
- 用WidgeDuino创建一个SCADA(监控与数据採集)系统
WidgeDuino – 近期在Kickstarter上亮相 – 是一个智能的易配置的窗体- 基于Microsoft Windows平台和基于像 Atmel-based Arduino board 的 ...
- 开源消息中间件DotNetMQ
由于这个开源项目对我这种中间件菜鸟很有帮助,因此,我将官方的说明文档翻译如下: Introduction In this article, I will introduce a new and ind ...
- IM-即时通讯技术概述
IM-即时通讯技术概述 简述 即时通讯技术(IM)支持用户在线实时交谈.如果要发送一条信息,用户需要打开一个小窗口,以便让用户及其朋友在其中输入信息并让交谈双方都看到交谈的内容.大多数常用的即时通讯发 ...
- web前端工程师在移动互联网时代里的地位问题 为啥C/S系统在PC端没有流行起来,却在移动互联网下流行了起来 为啥移动端的浏览器在很多应用里都是靠边站,人们更加倾向于先麻烦自己一下,下载安装个客户端APP
web前端工程师在移动互联网时代里的地位问题 支付宝十周年推出了一个新产品:支付宝的十年账单,我也赶个时髦查看了一下我的支付宝十年账单,哎,感慨自己真是太屌丝了,不过这只是说明我使用淘宝少了,当我大规 ...
- 消息通讯之关于消息队列MQ必须了解的相关概念
目录 系统通讯方式有哪些? 消息队列的应用场景 消息队列通讯模型 常见的消息协议 AMQP MQTT ATOMP JMS 小结 系统通讯方式有哪些? RPC调用 RPC 全称 Remote Proce ...
- linux 让程序在后台运行的几种可靠方法
我们经常会碰到这样的问题,用 telnet/ssh 登录了远程的 Linux 服务器,运行了一些耗时较长的任务, 结果却由于网络的不稳定导致任务中途失败.如何让命令提交后不受本地关闭终端窗口/网络断开 ...
- LoadRunner培训初级教程
一 LoadRunner简介 1.1 Loadrunner介绍 LoadRunner 是 HP Mercury Interactive 用来测试应用程序性能的工具 LoadRunner 通过模拟一个 ...
随机推荐
- create Context Menu in Windows Forms application using C# z
In this article let us see how to create Context Menu in Windows Forms application using C# Introduc ...
- [LeetCode]LRU Cache有个问题,求大神解答【已解决】
题目: Design and implement a data structure for Least Recently Used (LRU) cache. It should support the ...
- Cppcheck代码分析(2)
功能 解析函数中的可能的代码执行流 函数实际执行中只会执行代码流中的一条流 分析: 分支语句 if-else ,switch-case 循环语句 while, do-while ,for 代码流举例 ...
- r语言入门资料
最近有好多r语言的爱好者问我r语言的事情,在百度上简单的收一收,感觉都在扯淡,真正适合初学者入门的资料几乎没有,比如最开始用什么编辑器比较好,在哪下载,最开始学习的例子有什么? 在日本网站上反倒是找 ...
- 【原创】alias与export
最近在看lualua相关的,其中k中有os.getenv('kroot'),看到~/.bashrc理由kroot但是为什么拿不到,后来发现写成了alias了,应该是export的. alias rer ...
- 在virtualbox上安装mac os mavericks遇到Missing Bluetooth Controller Transport问题解决办法
挂载 HackBoot_Mav.iso 作为光驱,启动在 磁盘选择 界面,选择磁盘后按空格键,输入 启动参数 -v -x(-x的意思是安全模式,不这样的话,有蓝牙驱动作怪, 会输出 [IOBlueto ...
- 独树一帜的字符串匹配算法——RK算法
参加了雅虎2015校招,笔试成绩还不错,谁知初面第一题就被问了个字符串匹配,要求不能使用KMP,但要和KMP一样优,当时瞬间就呵呵了.后经过面试官的一再提示,也还是没有成功在面试现场写得.现将该算法记 ...
- magento 列表页显示产品属性值的几种调用方式
之前有人提到要在列表显示一些特定的属性,除了自带的名字,价格等.因为列表页和产品页都有一个同名的产品对象:$_product,而在产品页,$_product是直接可以用$_product->ge ...
- 没有指针的java语言
一.java中引用(reference)实质就是指针 与C语言的指针比较: 1.引用是受控的安全的 2.空引用会被检查 java中不能够访问没有引用到的内存,这也是java的自动垃圾回收机制的基础之一 ...
- ECSHOP在线手册布局参考图--通用活动页 group_list.dwt等
A.购物车 1,设置方法 程序自动读取购物车的商品数量 2,代码相关 cart.lbi 中 {insert_scripts files='transport.js'} <div clas ...