很久都没有写博客了,从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的更多相关文章

  1. 【翻译】DotNetMQ: 一个.NET版完整的消息队列系统

    在一个大型的分布式系统中,消息队列是不可缺少的中间件,能很好的解决异步消息.应用解耦.均衡并发等问题.在.net中,偶然发现一个效率不错.安全可靠.功能齐全的消息组件,忍不住翻译过来,供大家快速预览. ...

  2. Windows Azure Service Bus Topics实现系统松散耦合

    前言 Windows Azure中的服务总线(Service Bus)提供了多种功能, 包括队列(Queue), 主题(Topic),中继(Relay),和通知中心(Notification Hub) ...

  3. 用WidgeDuino创建一个SCADA(监控与数据採集)系统

    WidgeDuino – 近期在Kickstarter上亮相 – 是一个智能的易配置的窗体- 基于Microsoft Windows平台和基于像 Atmel-based Arduino board 的 ...

  4. 开源消息中间件DotNetMQ

    由于这个开源项目对我这种中间件菜鸟很有帮助,因此,我将官方的说明文档翻译如下: Introduction In this article, I will introduce a new and ind ...

  5. IM-即时通讯技术概述

    IM-即时通讯技术概述 简述 即时通讯技术(IM)支持用户在线实时交谈.如果要发送一条信息,用户需要打开一个小窗口,以便让用户及其朋友在其中输入信息并让交谈双方都看到交谈的内容.大多数常用的即时通讯发 ...

  6. web前端工程师在移动互联网时代里的地位问题 为啥C/S系统在PC端没有流行起来,却在移动互联网下流行了起来 为啥移动端的浏览器在很多应用里都是靠边站,人们更加倾向于先麻烦自己一下,下载安装个客户端APP

    web前端工程师在移动互联网时代里的地位问题 支付宝十周年推出了一个新产品:支付宝的十年账单,我也赶个时髦查看了一下我的支付宝十年账单,哎,感慨自己真是太屌丝了,不过这只是说明我使用淘宝少了,当我大规 ...

  7. 消息通讯之关于消息队列MQ必须了解的相关概念

    目录 系统通讯方式有哪些? 消息队列的应用场景 消息队列通讯模型 常见的消息协议 AMQP MQTT ATOMP JMS 小结 系统通讯方式有哪些? RPC调用 RPC 全称 Remote Proce ...

  8. linux 让程序在后台运行的几种可靠方法

    我们经常会碰到这样的问题,用 telnet/ssh 登录了远程的 Linux 服务器,运行了一些耗时较长的任务, 结果却由于网络的不稳定导致任务中途失败.如何让命令提交后不受本地关闭终端窗口/网络断开 ...

  9. LoadRunner培训初级教程

    一 LoadRunner简介 1.1 Loadrunner介绍 LoadRunner 是 HP Mercury Interactive 用来测试应用程序性能的工具  LoadRunner 通过模拟一个 ...

随机推荐

  1. SharePoint 2010 master page 控件介绍(1)

    转:http://blog.csdn.net/lgm97/article/details/6409204 以下所有的内容都是根据Randy Drisgill (MVP SharePoint Serve ...

  2. ChineseCounter.cs 统计中文文本中常用字占比

    http://www.tuicool.com/articles/qmMba2 1 using System; using System.IO; using System.Collections.Gen ...

  3. HDU 3001 Travelling 3进制状压dp

    题意:10个点,若干条边,边有花费,每个点最多走两次,求走过所有点,花费最少 分析:因为每个点最多走两次,所以联想到3进制,然后枚举状态,就行了(我也是照着网上大神的代码写的) #include &l ...

  4. 《Python基础教程(第二版)》学习笔记 -> 第三章 使用字符串

    本章讲话介绍如何使用字符串格式化其他的值,并简单了解一下利用字符串的分割.联接.搜索等方法能做些什么. 基本字符串操作 所有标准的序列操作(索引.分片.乘法.判断成员资格.求长度.取最大最小值)对字符 ...

  5. 发送一个简单的HTTP GET请求并且取回响应。

    string uri="http//www.baidu.com"; WebClient wc = new WebClient(); Console.WriteLine(" ...

  6. 【译】 AWK教程指南 2概述

    2.1 为什么用AWK 由于awk具有上述特色,在问题处理的过程中,可轻易使用awk来撰写一些小工具:这些小工具并非用来解决整个大问题,它们只扮演解决个别问题过程的某些角色,可通过Shell所提供的p ...

  7. Tomcat 7 Connector 精读(2) CoyoteAdapter

    这个适配器类只讲2个方法,构造方法中我们看到一个适配器对象有自己关联的连接器类. 其中Service的重要任务就是讲客户端端请求交给容器. public void service(org.apache ...

  8. Tomcat问题笔记

    1. Tomcat服务器只能同步WebContent目录到webapps下面,如果WebContent里面的.html文件引用了与WebContent文件夹同级目录下的一个.js文件,Tomcat服务 ...

  9. 使用weka进行Cross-validation实验

    Generating cross-validation folds (Java approach) 文献: http://weka.wikispaces.com/Generating+cross-va ...

  10. uva 11178

    题意:根据A,B,C三点的位置确定D,E,F三个点的位置. 贴模板 #include<cstdio> #include<cmath> #include<cstring&g ...