多系统通讯-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 通过模拟一个 ...
随机推荐
- less命令
less命令的作用与more十分相似,都可以用来浏览文字档案的内容,不同的是less命令允许用户向前或向后浏览文件,而more命令只能向前浏览.用less命令显示文件时,用PageUp键向上翻页,用P ...
- 总结1-JMeter压力测试
考虑到测试最需要逻辑能力,所以今天开始慢慢写些东西,希望能自我锻炼下. 第一个课题是压力测试,会把我了解到的和百度的东西按我的思路整合一下 一 什么是压力测试 二 压力测试所需要关注的参数 三 怎么做 ...
- <转>LeetCode 题目总结/分类
原链接:http://blog.csdn.net/yangliuy/article/details/44514495 注:此分类仅供大概参考,没有精雕细琢.有不同意见欢迎评论~ 利用堆栈:http:/ ...
- sys.stdout 重定向
通俗的来说,sys.stdout的功能类似与C++里面的文件输出功能fprintf. 接下来直接入正题,让我们来看代码: >>> import sys >>> te ...
- VIJOS-P1340 拯救ice-cream(广搜+优先级队列)
题意:从s到m的最短时间.(“o"不能走,‘#’走一个花两个单位时间,‘.'走一个花一个单位时间) 思路:广搜和优先队列. #include <stdio.h> #include ...
- 关于硬盘和几种RAID
1 硬盘的基本工作原理 1.1 硬盘部件结构图 1.2 主要参数术语解释 磁头:在与硬盘交换数据的过程 中,读操作远远快于写操作,硬盘厂商开发一种读/写分离磁头. 转速(Rotationl Speed ...
- Hive基础介绍
HIVE结构 Hive 是建立在 Hadoop 上的数据仓库基础构架.它提供了一系列的工具,可以用来进行数据提取转化加载(ETL),这是一种可以存储.查询和分析存储在 Hadoop 中的大规模数据的机 ...
- HDU-4655 Cut Pieces 数学,贪心
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4655 先不考虑相临的有影响,那么总数就是n*prod(ai),然后减去每个相邻的对总数的贡献Σ( Mi ...
- HDU-3487 Play with Chain Splay tee区间反转,移动
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3487 对于一个数列有两种操作:1.CUT a b c,先取出a-b区间的数,然后把它们放在取出后的第c ...
- 再次踩bug:遍历删除list(java.util.ConcurrentModificationException)
再次踩bug:遍历删除list(java.util.ConcurrentModificationException) 使用 List<Long> list = new ArrayList& ...