很久都没有写博客了,从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

简单的画个图可以更加方便的去了解这个结构

多系统通讯-DotNetMQ

通过这个图我们可以看到,在多个客户端通讯之前需要先开启服务,然后通过唯一性的token我们就可以做到客户端之间的信息通讯。

下载下来的应该是一个服务的启动程序和一个管理端,经过包装和更改更加方便使用一些:

多系统通讯-DotNetMQ

两个服务

1..NETMQ本身的服务

2.添加令牌的服务,开放成对外的wcf接口,可以通过接口取添加令牌。

多系统通讯-DotNetMQ

关于服务配置其实修改后只需要服务端口就行了,连接通过地址和端口号就可以连接。

 

 多系统通讯-DotNetMQ

最后就是令牌了,令牌就是客户端之间通讯的一个token,就是一个唯一的识别信息,就跟qq一样,给妹子发信息总要知道人家的qq号吧,token其实也可以这么理解。

客户端上线之后就客户端连接就是1。

通过上述的描述我想基本都对这个有一个印象了,通过这些印象我们可以想象到他的应用场景,比如去做一个聊天工具,做上传下载的进度提示,等等。

了解了应用场景我们就应该去想想我们怎么样才能简单而又方便的把它应用在我们的项目中,可以解决我们产品和项目中的实际问题。

 

服务端:

多系统通讯-DotNetMQ

图中可以看到,我们下载下来的.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

相关文章: