多系统通讯-DotNetMQ
很久都沒有寫博客了,從15年4月份一直忙到現(xiàn)在,我才有時(shí)間去做梳理和總結(jié),因?yàn)槲姨犭x職了,感覺整個(gè)世界突然變得不一樣,隨著而來的就是心情的放松,寫一篇文章也是對(duì)過去一年多工作的梳理,加深印象 積累和沉淀。
因?yàn)閺氖碌墓臼墙ㄖ袠I(yè)的公司,產(chǎn)品也是基于建筑管理體系,整體的項(xiàng)目包含了web端、客戶端、服務(wù)端,以及因?yàn)楫a(chǎn)品功能需要的一些工具類的軟件。在這種多系統(tǒng)的體系結(jié)構(gòu)之下,我們需要進(jìn)行多個(gè)系統(tǒng)之間的實(shí)時(shí)通訊,其實(shí)做到實(shí)時(shí)通訊的方式有很多種
1.sql server的Server_borker ? ?數(shù)據(jù)變更通知,是基于sql server數(shù)據(jù)庫的,表中的數(shù)據(jù)變更會(huì)通知到監(jiān)聽的那端,但是覺得考慮到通訊比較頻繁,通訊端比較多,這種方式很容易造成代碼上和程序上的混亂,不做考慮。
2.wcf的消息廣播 ? 相比第一種,這個(gè)對(duì)于這種多系統(tǒng)通訊更加不具備優(yōu)勢(shì)。這種在服務(wù)端進(jìn)行操作,客戶端通過注冊(cè)來監(jiān)聽服務(wù)端處理的進(jìn)度很明顯不適合兩個(gè)或者多個(gè)客戶端之間的通信,我們的系統(tǒng)可不僅僅限于客戶端服務(wù)端這么簡單,不做考慮。
3..NetMQ 就是本章中要介紹的解決多系統(tǒng)通訊問題的殺手锏了。這個(gè)其實(shí)在最開始是我們同事去下載研究的,在之后經(jīng)過一些包裝可以很方便的去使用,接下來我們?nèi)ヒ黄鹆私庖幌隆?/p>
下載地址:http://www.codeproject.com/Articles/193611/DotNetMQ-A-Complete-Message-Queue-System-for-NET
簡單的畫個(gè)圖可以更加方便的去了解這個(gè)結(jié)構(gòu)
通過這個(gè)圖我們可以看到,在多個(gè)客戶端通訊之前需要先開啟服務(wù),然后通過唯一性的token我們就可以做到客戶端之間的信息通訊。
下載下來的應(yīng)該是一個(gè)服務(wù)的啟動(dòng)程序和一個(gè)管理端,經(jīng)過包裝和更改更加方便使用一些:
兩個(gè)服務(wù)
1..NETMQ本身的服務(wù)
2.添加令牌的服務(wù),開放成對(duì)外的wcf接口,可以通過接口取添加令牌。
關(guān)于服務(wù)配置其實(shí)修改后只需要服務(wù)端口就行了,連接通過地址和端口號(hào)就可以連接。
?
?
最后就是令牌了,令牌就是客戶端之間通訊的一個(gè)token,就是一個(gè)唯一的識(shí)別信息,就跟qq一樣,給妹子發(fā)信息總要知道人家的qq號(hào)吧,token其實(shí)也可以這么理解。
客戶端上線之后就客戶端連接就是1。
通過上述的描述我想基本都對(duì)這個(gè)有一個(gè)印象了,通過這些印象我們可以想象到他的應(yīng)用場(chǎng)景,比如去做一個(gè)聊天工具,做上傳下載的進(jìn)度提示,等等。
了解了應(yīng)用場(chǎng)景我們就應(yīng)該去想想我們?cè)趺礃硬拍芎唵味址奖愕陌阉鼞?yīng)用在我們的項(xiàng)目中,可以解決我們產(chǎn)品和項(xiàng)目中的實(shí)際問題。
?
服務(wù)端:
圖中可以看到,我們下載下來的.NETMQ在服務(wù)端只需要引用這三個(gè)庫就可以了,
MQServer就是我們針對(duì)實(shí)際項(xiàng)目應(yīng)用做的一些修改,將服務(wù)開啟、停止、令牌的添加刪除以及管理都在這里做了包裝,只需要去引用就可以了。
/// <summary>/// 消息中心服務(wù)器端管理類/// </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>/// 服務(wù)是否處于開啟狀態(tài)/// </summary>public bool IsOpened { get; set; }#endregion#region 構(gòu)造方法public MQService(){server = new MDSServer();}#endregion #region 開啟服務(wù)/// <summary>/// 開啟服務(wù)/// </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 關(guān)閉服務(wù)/// <summary>/// 關(guān)閉服務(wù)/// </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服務(wù)端簡單的使用就是這些,詳細(xì)的介紹以及內(nèi)部原理網(wǎng)上很多,這里就不介紹了。
?
客戶端:
關(guān)于客戶端呢,為了便于更方便的使用我寫一個(gè)簡單的demo去演示一下。
圖中紅框的部分其實(shí)就是MDSCommonLib這個(gè)庫,下面幾個(gè)類就是對(duì)外的事件和方法的包裝,我們可以看一下代碼:
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>/// 接收消息回執(zhí)事件/// </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>/// 接收消息回執(zhí)事件/// </summary>/// <param name="sender"></param>/// <param name="e"></param>void client_OnMessageReceived(object sender, MessageReceiveEventArgs e){if (OnMessageReceived != null){OnMessageReceived(sender, e);}}/// <summary>/// 發(fā)送消息/// </summary>/// <param name="messageContent"></param>public void SendMessage(string messageContent, string tokenName){client.SendMessage(messageContent, tokenName);}/// <summary>/// 開啟服務(wù)/// </summary>public void Start(string tokenName){client.StartConnection("127.0.0.1", 10905, tokenName);}/// <summary>/// 關(guān)閉服務(wù)/// </summary>public void Stop(){client.StopConnection();}} View Code這是最外層的包裝,通過這些就可以去調(diào)用
MQClientLib.MQMessage.Instance.Start("User_Sean");
?
客戶端開啟連接的方式僅僅這樣就可以了,通過這行表示:User_Sean上線了。
這樣我們?cè)诜?wù)端就可以看到User_Sean的連接:
?
?
吶,這是一個(gè)客戶端,如果是多個(gè)客戶端連接上了呢? 我們就可以通過
?
/// <summary>/// 發(fā)送消息/// </summary>/// <param name="messageContent"></param>public void SendMessage(string messageContent, string tokenName){client.SendMessage(messageContent, tokenName);}調(diào)用這行代碼去向其它客戶端發(fā)送信息,其它客戶端接收到信息的時(shí)候也會(huì)觸發(fā)這邊的回執(zhí)事件。
/// <summary>/// 接收消息回執(zhí)事件/// </summary>public event EventHandler OnResponseMessageReceived;通過注冊(cè)這個(gè)事件,在對(duì)方接收到你發(fā)送的消息的時(shí)候,可以觸發(fā)這個(gè)事件。
/// <summary>
/// 接收消息事件
/// </summary>
public event EventHandler OnMessageReceived;
這個(gè)是用來接收別人給你發(fā)送的信息的,信息通過這個(gè)時(shí)間的sender傳遞過來。
?
使用暫時(shí)就這些,因?yàn)榇a是加密的,所以只能以后去重新做一下然后給各位提供下載地址了。
當(dāng)然,關(guān)于mq的使用dotNetMQ只是其中一項(xiàng),今天介紹的也只是通訊,之后下一篇博客會(huì)介紹相關(guān)的msmq、queue等等,后面精彩繼續(xù)~~~~~?
轉(zhuǎn)載于:https://www.cnblogs.com/BeiJing-Net-DaiDai/p/6030941.html
總結(jié)
以上是生活随笔為你收集整理的多系统通讯-DotNetMQ的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数据结构与算法分析
- 下一篇: g4600黑苹果efi_超详细黑苹果安装