多系统通讯-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 通过模拟一个 ...
随机推荐
- Spring基础知识及bean的配置
IOC与DI: IOC(inversion of control):其思想是反转资源获取的方向.传统的资源查找方式要求组件向容器发起请求查找资源.作为回应,容器适时的返回资源.而应用了IOC之后,则是 ...
- Eclipse中出现Select at least one project解决办法
今天遇到个问这个问题的,顺便帮解决了,是在导入工程的时候出现的,这是因为有同名的工程的,进入windows->show view->project explorer 这里找出来删掉再导入工 ...
- JSON--List集合转换成JSON对象
转自:http://www.cnblogs.com/xmaomao/p/3184542.html 1. 简单的手动放置 键值对 到JSONObject,然后在put到JSONArray对象里 List ...
- SSL 通信原理及Tomcat SSL 配置
SSL 通信原理及Tomcat SSL 双向配置 目录1 参考资料 .................................................................. ...
- Linux创建公钥
A:192.168.1.1 B:192.168.1.2 现在想让A无密码登陆B机器 A上运行以下命令来生成公钥和私钥 ssh-keygen -t rsa -P '' 运行该命令后会生成如下两个文件 ...
- 【学习干货】给coder的10个读书建议
1.知识更新非常快,大学一毕业就已经有40%的知识过时,一年不读书80%过时,三年不读书99%过时.这就要求我们不间断阅读,每年每月每星期每天都要阅读,只有长期的阅读才能不被淘汰:也只有长期阅读,才能 ...
- 打印出从1到最大的n位十进制数
首先这一题会溢出,要考虑的大数问题.所以不能用简单的是int类型数来表示(32位无符号int 范围是0x00000000···0xFFFFFFFF),下面主要是非递归的实现代码,自己做了注释方便以后回 ...
- NIOP1995 石子合并(区间DP)
状态转移方程在代码中标出 本题注意是圆形,所以之前要预先处理一下s数组.处理之后总长度为2*n-1.第一个合并的起点有n个,所以总的方案数是n 注释在代码中标出 http://www.rqnoj.cn ...
- use tomcat to access the file cross the environment
background: 项目中的一个小工具,是一个Cron Job ,每天去搜集下服务器Hadoop Job的运行状态,并生成一份报告发送给整个Team,生产报告的同时把相关的日志文件保存到固定的一台 ...
- 广州大学华软软件学院——NA视频下载
准备工具: 360极速浏览器(不要认错图标了): 浏览器视频下载插件: 第一步:安装浏览器插件 1.打开浏览器 2.解压,找到插件文件: 3.把插件拖到浏览器中: 4.添加,然后就完成了插件安装 查看 ...