多系統通訊-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}
View Code

服務端簡單的使用就是這些,詳細的介紹以及內部原理網上很多,這里就不介紹了。

?

客戶端:

關于客戶端呢,為了便于更方便的使用我寫一個簡單的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", 10905, tokenName);}/// <summary>/// 關閉服務/// </summary>public void Stop(){client.StopConnection();}}
View Code

這是最外層的包裝,通過這些就可以去調用

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等等,后面精彩繼續~~~~~?

轉載于:https://www.cnblogs.com/BeiJing-Net-DaiDai/p/6030941.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/260207.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/260207.shtml
英文地址,請注明出處:http://en.pswp.cn/news/260207.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

九大現代病!中槍了嗎?

現代人在享受現代化的生活和工作方式帶來的便捷之時&#xff0c;也為此付出了不小的代價&#xff0c;下面列出的九大現代病就是典型的例子&#xff0c;看看你有沒有中槍。 辦公臀 常坐辦公室&#xff0c;如果你發現屁股越坐越大&#xff0c;大腿越坐越粗&#xff0c;你可能有了…

Java學習筆記(4)——枚舉類型

1.在類別&#xff08;Class&#xff09;或接口&#xff08;Interface&#xff09;中宣告常數加以管理&#xff0c;這只是讓您存取與管理常數方便而已&#xff0c;來看看這個例子&#xff1a; public void someMethod() {....doOp(OpConstants.TURN_RIGHT);.... } public void d…

驅動提取軟件_深入分析施耐德工控軟件代碼執行漏洞

更多全球網絡安全資訊盡在邑安全簡介在本文中&#xff0c;我們將為讀者詳細介紹Claroty Research團隊的Amir Preminger和Sharon Brizinov是如何組合利用兩個漏洞&#xff0c;來觸發施耐德工控軟件EcoStruxure Operator Terminal Expert的代碼執行漏洞&#xff0c;從而在首屆舉辦…

ubuntu 網卡突然無法連接

今天要用到VM BT的Namp掃描服務器端口&#xff0c;發現橋接后無法使用。ifconfig 只看到 lo地址&#xff0c;看不到以太網網卡地址使用lspci 查看是否安裝了以太網網卡驅動lscpi | grep Ethernet02:01.0 Ethernet controller: Advanced Micro Devices [AMD] 79c970 [PCnet32 LA…

atitit.表單驗證 的dsl 本質跟 easyui ligerui比較

atitit.表單驗證的dsl 本質跟 easyui ligerui比較 1. DSL 聲明驗證 1 2. 自定義規則 1 3. 正則表達式驗證,可以擴展實現 2 4. 犯錯誤消息提示,generic canBeEmpty is good 3 5. Prevent the form to submit when invalid 3 6. 為空則不驗證&#xff0c;不為空則驗證&#xff0…

StartActivityForResult

StartActivity 用startActivityForResult(intent, requestcode);啟動子功能模塊activity onActivityResult(int requestCode, int resultCode, Intent data)對子activity返回進行判斷處理 public class StartActivity extends Activity implements OnClickListener {private Bu…

micropython 串口寫文件_MicroPython通過2G模塊串口收發短信

集成2G通信、定位模組&#xff0c;賦予物聯網特性。本例使用M6220&#xff0c;它是一款基于eSIM技術的2G模組&#xff0c;支持GSM/GPRS&#xff0c;提供GPS北斗雙模定位功能&#xff0c;并具備一定的數據處理能力&#xff0c;其2G工作頻段有GSM850、GSM900、DCS1800和PCS1900&a…

洛谷P1130 紅牌

題目描述 某地臨時居民想獲得長期居住權就必須申請拿到紅牌。獲得紅牌的過程是相當復雜 &#xff0c;一共包括N個步驟。每一步驟都由政府的某個工作人員負責檢查你所提交的材料是否符合條件。為了加快進程&#xff0c;每一步政府都派了M個工作人員來檢查材料。不幸的是&#xf…

GPS坐標換算

30.8872 》——>300.8872*60 53.232 ——>530.232*60 13.9230: 53 13.92"30: 53 13.92"》3053/6013.92/360030.887199同經度兩點之間距離dla30.887m * [差值/(1/3600)] 30.887m * 差值 *3600 111193.2m * 差值 同緯度兩點之間距離dlo30.887m * [差值/(1…

企業級應用框架(五)IOC容器在框架中的應用

前言 在上一篇我大致的介紹了這個系列所涉及到的知識點&#xff0c;在本篇我打算把IOC這一塊單獨提取出來講&#xff0c;因為IOC容器在解除框架層與層之間的耦合有著不可磨滅的作用。當然在本系列前面的三篇中我也提供了一種基于反射的解耦方式&#xff0c;但是始終不是很優雅&…

后端開發需要學什么_都2020年了,還在糾結學什么語言?| 后端篇

幾個禮拜前&#xff0c;一個學弟問我&#xff1a;“Ray&#xff0c;我打算之后要找工作了&#xff0c;不過現在自己沒有特別深入的語言&#xff0c;最近想找一門好好學一下&#xff0c;你覺得學什么語言好呀&#xff1f;”我表示&#xff1a;“這個要看你求職方向、個人喜好、市…

python掃描ip的端口打開情況

我們的韓國bss系統上線之后&#xff0c;要求對主機的端口、資源使用進行統計&#xff0c;端口每個主機去看&#xff0c;太費勁了&#xff0c;所以&#xff0c;就寫了這樣一個小程序&#xff0c;不是很完美但是&#xff0c;可以用啊&#xff01;哈哈哈&#xff0c;別噴&#xff…

flash java 通信,Flash到JavaScript的通信實例

從HTML可以發送數據到Flash,反過來也可以. 這個例子演示了如何應用Flash的Fscommand來發送數據到Javascript.簡要步驟:Flash中新建一個文件,保存為flash_to_javascript.fla創建一個文本域,設置成輸入文本(Input Text),選擇"border"以便我們能看到他,指定他的變量為in…

10個非常有用的CSS hack和技術

轉自&#xff1a;http://www.qianduan.net/10-useful-css-hacks-and-technique.html 1 – 跨瀏覽器的inline-block <style>li {width: 200px;min-height: 250px;border: 1px solid #000;display: -moz-inline-stack;display: inline-block;margin: 5px;zoom: 1;*display:…

Java的遞歸算法

遞歸算法設計的基本思想是&#xff1a;對于一個復雜的問題&#xff0c;把原問題分解為若干個相對簡單類同的子問題&#xff0c;繼續下去直到子問題簡單到可以直接求解&#xff0c;也就是說到了遞推的出口&#xff0c;這樣原問題就有遞推得解。 關鍵要抓住的是&#xff1a; &…

python list遍歷定位元素_python for循環,第二遍定位不到元素?

ycyzharry: 也不行&#xff0c;我的代碼import unittestimport timeimport xlrdfrom selenium import webdriverimport seleniumdef open_excel(filefile.xls):try:data xlrd.open_workbook(file)return dataexcept Exception as e:print(str(e))def excel_table_byindex(file…

發現Java程序中的Bug

昨天在CSDN上閱讀 "Java中十個常見的違規編碼"這篇文章時&#xff0c;無意中找到了3個 "發現Java程序中的Bug"工具。 文章地址&#xff1a;http://www.csdn.net/article/2012-09-11/2809829-common-code-violations-in-java其中&#xff0c; FindBugs? - …

原生php登錄注冊,原生php登陸注冊

本以為一個登陸注冊功能十來分鐘就寫好了&#xff0c;沒想到thinkPHP用久了&#xff0c;原生的php不會寫了最開始我直接寫了類和方法&#xff0c;在前臺傳遞參數給類的login方法(action"index.php/login"),嘗試幾次發現無法訪問&#xff0c;這才意識到&#xff0c;這…

SpringMVC REST 風格靜態資源訪問配置

1 在web.xml中使用默認servlet處理靜態資源&#xff0c;缺點是如果靜態資源過多&#xff0c;則配置量會比較大&#xff0c;一旦有遺漏&#xff0c;則會造成資源無法正常顯示或404錯誤。 <!-- 靜態資源訪問控制 --><servlet-mapping><servlet-name>default<…

生成對象

var c[name,age,city]; var d[xiaogang,12,anhui]; var a{}; for(var i0;i<3;i){a[c[i]]d[i]; } console.log(a); //返回 {name: "xiaogang", age: "12", city: "anhui"} 轉載于:https://www.cnblogs.com/xiaozhumaopao/p/6046823.html