ActiveMQ在C#中的應(yīng)用示例分析
本文實(shí)例講述了ActiveMQ在C#中的應(yīng)用。分享給大家供大家參考,具體如下:
ActiveMQ是個(gè)好東東,不必多說。ActiveMQ提供多種語言支持,如Java, C, C++, C#, Ruby, Perl, Python, PHP等。由于我在windows下開發(fā)GUI,比較關(guān)心C++和C#,其中C#的ActiveMQ很簡(jiǎn)單,Apache提供NMS(.Net Messaging Service)支持.Net開發(fā),只需如下幾個(gè)步驟即能建立簡(jiǎn)單的實(shí)現(xiàn)。C++的應(yīng)用相對(duì)麻煩些,后面會(huì)有文章介紹。
1、去ActiveMQ官方網(wǎng)站下載最新版的ActiveMQ,網(wǎng)址:http://activemq.apache.org/download.html。我之前下的是5.3.1,5.3.2現(xiàn)在也已經(jīng)出來了。
2、去ActiveMQ官方網(wǎng)站下載最新版的Apache.NMS,網(wǎng)址:http://activemq.apache.org/nms/download.html,需要下載Apache.NMS和Apache.NMS.ActiveMQ兩個(gè)bin包,如果對(duì)源碼感興趣,也可下載src包。這里要提醒一下,如果下載1.2.0版本的NMS.ActiveMQ,Apache.NMS.ActiveMQ.dll在實(shí)際使用中有個(gè)bug,即停止ActiveMQ應(yīng)用時(shí)會(huì)拋WaitOne函數(shù)異常,查看src包中的源碼發(fā)現(xiàn)是由于Apache.NMS.ActiveMQ-1.2.0-src\src\main\csharp\Transport\InactivityMonitor.cs中的如下代碼造成的,修改一下源碼重新編譯即可??戳艘幌伦钚掳?.3.0已經(jīng)修復(fù)了這個(gè)bug,因此下載最新版即可。
private void StopMonitorThreads()
{
lock(monitor)
{
if(monitorStarted.CompareAndSet(true, false))
{
AutoResetEvent shutdownEvent = new AutoResetEvent(false);
// Attempt to wait for the Timers to shutdown, but don't wait
// forever, if they don't shutdown after two seconds, just quit.
this.readCheckTimer.Dispose(shutdownEvent);
shutdownEvent.WaitOne(TimeSpan.FromMilliseconds(2000));
this.writeCheckTimer.Dispose(shutdownEvent);
shutdownEvent.WaitOne(TimeSpan.FromMilliseconds(2000));
//WaitOne的定義:public virtual bool WaitOne(TimeSpan timeout,bool exitContext)
this.asyncTasks.Shutdown();
this.asyncTasks = null;
this.asyncWriteTask = null;
this.asyncErrorTask = null;
}
}
}
3、運(yùn)行ActiveMQ,找到ActiveMQ解壓后的bin文件夾:...\apache-activemq-5.3.1\bin,執(zhí)行activemq.bat批處理文件即可啟動(dòng)ActiveMQ服務(wù)器,默認(rèn)端口為61616,這可在配置文件中修改。
4、寫C#程序?qū)崿F(xiàn)ActiveMQ的簡(jiǎn)單應(yīng)用。新建C#工程(一個(gè)Producter項(xiàng)目和一個(gè)Consumer項(xiàng)目),WinForm或Console程序均可,這里建的是Console工程,添加對(duì)Apache.NMS.dll和Apache.NMS.ActiveMQ.dll的引用,然后即可編寫實(shí)現(xiàn)代碼了,簡(jiǎn)單的Producer和Consumer實(shí)現(xiàn)代碼如下:
producer:
using System;
using System.Collections.Generic;
using System.Text;
using Apache.NMS;
using Apache.NMS.ActiveMQ;
using System.IO;
using System.Xml.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
namespace Publish
{
class Program
{
static void Main(string[] args)
{
try
{
//Create the Connection Factory
IConnectionFactory factory = new ConnectionFactory("tcp://localhost:61616/");
using (IConnection connection = factory.CreateConnection())
{
//Create the Session
using (ISession session = connection.CreateSession())
{
//Create the Producer for the topic/queue
IMessageProducer prod = session.CreateProducer(
new Apache.NMS.ActiveMQ.Commands.ActiveMQTopic("testing"));
//Send Messages
int i = 0;
while (!Console.KeyAvailable)
{
ITextMessage msg = prod.CreateTextMessage();
msg.Text = i.ToString();
Console.WriteLine("Sending: " + i.ToString());
prod.Send(msg, Apache.NMS.MsgDeliveryMode.NonPersistent, Apache.NMS.MsgPriority.Normal, TimeSpan.MinValue);
System.Threading.Thread.Sleep(5000);
i++;
}
}
}
Console.ReadLine();
}
catch (System.Exception e)
{
Console.WriteLine("{0}",e.Message);
Console.ReadLine();
}
}
}
}
consumer:
using System;
using System.Collections.Generic;
using System.Text;
using Apache.NMS;
using Apache.NMS.ActiveMQ;
using System.IO;
using System.Xml.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
namespace Subscribe
{
class Program
{
static void Main(string[] args)
{
try
{
//Create the Connection factory
IConnectionFactory factory = new ConnectionFactory("tcp://localhost:61616/");
//Create the connection
using (IConnection connection = factory.CreateConnection())
{
connection.ClientId = "testing listener";
connection.Start();
//Create the Session
using (ISession session = connection.CreateSession())
{
//Create the Consumer
IMessageConsumer consumer = session.CreateDurableConsumer(new Apache.NMS.ActiveMQ.Commands.ActiveMQTopic("testing"), "testing listener", null, false);
consumer.Listener += new MessageListener(consumer_Listener);
Console.ReadLine();
}
connection.Stop();
connection.Close();
}
}
catch (System.Exception e)
{
Console.WriteLine(e.Message);
}
}
static void consumer_Listener(IMessage message)
{
try
{
ITextMessage msg = (ITextMessage)message;
Console.WriteLine("Receive: " + msg.Text);
}
catch (System.Exception e)
{
Console.WriteLine(e.Message);
}
}
}
}
程序?qū)崿F(xiàn)的功能:生產(chǎn)者producer建立名為testing的主題,并每隔5秒向該主題發(fā)送消息,消費(fèi)者consumer訂閱了testing主題,因此只要生產(chǎn)者發(fā)送testing主題的消息到ActiveMQ服務(wù)器,服務(wù)器就將該消息發(fā)送給訂閱了testing主題的消費(fèi)者。
編譯生成producer.exe和consumer.exe,并執(zhí)行兩個(gè)exe,即可看到消息的發(fā)送與接收了。
這個(gè)例子是建的主題(Topic),ActiveMQ還支持另一種方式:Queue,即P2P,兩者有什么區(qū)別呢?區(qū)別在于,Topic是廣播,即如果某個(gè)Topic被多個(gè)消費(fèi)者訂閱,那么只要有消息到達(dá)服務(wù)器,服務(wù)器就將該消息發(fā)給全部的消費(fèi)者;而Queue是點(diǎn)到點(diǎn),即一個(gè)消息只能發(fā)給一個(gè)消費(fèi)者,如果某個(gè)Queue被多個(gè)消費(fèi)者訂閱,沒有特殊情況的話消息會(huì)一個(gè)一個(gè)地輪流發(fā)給不同的消費(fèi)者,比如:
msg1-->consumer A
msg2-->consumer B
msg3-->consumer C
msg4-->consumer A
msg5-->consumer B
msg6-->consumer C
特殊情況是指:ActiveMQ支持過濾機(jī)制,即生產(chǎn)者可以設(shè)置消息的屬性(Properties),該屬性與消費(fèi)者端的Selector對(duì)應(yīng),只有消費(fèi)者設(shè)置的selector與消息的Properties匹配,消息才會(huì)發(fā)給該消費(fèi)者。Topic和Queue都支持Selector。
Properties和Selector該如何設(shè)置呢?請(qǐng)看如下代碼:
producer:
ITextMessage msg = prod.CreateTextMessage();
msg.Text = i.ToString();
msg.Properties.SetString("myFilter", "test1");
Console.WriteLine("Sending: " + i.ToString());
prod.Send(msg, Apache.NMS.MsgDeliveryMode.NonPersistent, Apache.NMS.MsgPriority.Normal, TimeSpan.MinValue);
consumer:
//生成consumer時(shí)通過參數(shù)設(shè)置Selector
IMessageConsumer consumer = session.CreateConsumer(new Apache.NMS.ActiveMQ.Commands.ActiveMQQueue("testing"), "myFilter='test1'");
更多關(guān)于C#相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《C#窗體操作技巧匯總》、《C#常見控件用法教程》、《WinForm控件用法總結(jié)》、《C#程序設(shè)計(jì)之線程使用技巧總結(jié)》、《C#操作Excel技巧總結(jié)》、《C#中XML文件操作技巧匯總》、《C#數(shù)據(jù)結(jié)構(gòu)與算法教程》、《C#數(shù)組操作技巧總結(jié)》及《C#面向?qū)ο蟪绦蛟O(shè)計(jì)入門教程》
希望本文所述對(duì)大家C#程序設(shè)計(jì)有所幫助。
欄 目:C#教程
下一篇:C#實(shí)現(xiàn)的字符串轉(zhuǎn)MD5碼函數(shù)實(shí)例
本文標(biāo)題:ActiveMQ在C#中的應(yīng)用示例分析
本文地址:http://www.jygsgssxh.com/a1/C_jiaocheng/6375.html
您可能感興趣的文章
- 01-10C#實(shí)現(xiàn)將窗體固定在顯示器的左上角且不能移動(dòng)的方法
- 01-10C#實(shí)現(xiàn)在Form里面內(nèi)嵌dos窗體的方法
- 01-10C#中查找Dictionary中的重復(fù)值的方法
- 01-10C#實(shí)現(xiàn)在啟動(dòng)目錄創(chuàng)建快捷方式的方法
- 01-10C#將圖片存放到SQL SERVER數(shù)據(jù)庫中的方法
- 01-10關(guān)于nancy中的身份驗(yàn)證
- 01-10C#中的事務(wù)用法實(shí)例分析
- 01-10C#編程自學(xué)之類和對(duì)象
- 01-10C#創(chuàng)建不規(guī)則窗體的4種方式詳解
- 01-10C#實(shí)現(xiàn)讀取DataSet數(shù)據(jù)并顯示在ListView控件中的方法


閱讀排行
- 1C語言 while語句的用法詳解
- 2java 實(shí)現(xiàn)簡(jiǎn)單圣誕樹的示例代碼(圣誕
- 3利用C語言實(shí)現(xiàn)“百馬百擔(dān)”問題方法
- 4C語言中計(jì)算正弦的相關(guān)函數(shù)總結(jié)
- 5c語言計(jì)算三角形面積代碼
- 6什么是 WSH(腳本宿主)的詳細(xì)解釋
- 7C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
- 8正則表達(dá)式匹配各種特殊字符
- 9C語言十進(jìn)制轉(zhuǎn)二進(jìn)制代碼實(shí)例
- 10C語言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法
本欄相關(guān)
- 01-10C#通過反射獲取當(dāng)前工程中所有窗體并
- 01-10關(guān)于ASP網(wǎng)頁無法打開的解決方案
- 01-10WinForm限制窗體不能移到屏幕外的方法
- 01-10WinForm繪制圓角的方法
- 01-10C#實(shí)現(xiàn)txt定位指定行完整實(shí)例
- 01-10WinForm實(shí)現(xiàn)仿視頻播放器左下角滾動(dòng)新
- 01-10C#停止線程的方法
- 01-10C#實(shí)現(xiàn)清空回收站的方法
- 01-10C#通過重寫Panel改變邊框顏色與寬度的
- 01-10C#實(shí)現(xiàn)讀取注冊(cè)表監(jiān)控當(dāng)前操作系統(tǒng)已
隨機(jī)閱讀
- 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?
- 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什
- 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改
- 01-11ajax實(shí)現(xiàn)頁面的局部加載
- 01-10使用C語言求解撲克牌的順子及n個(gè)骰子
- 04-02jquery與jsp,用jquery
- 01-10C#中split用法實(shí)例總結(jié)
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文
- 01-10delphi制作wav文件的方法
- 01-10SublimeText編譯C開發(fā)環(huán)境設(shè)置


