標籤:
NetMQ (ZeroMQ to .Net),ØMQ號稱史上最快中介軟體。它對socket通訊進行了封裝,使得我們不需要寫socket函數調用就能完成複雜的網路通訊。和一般意義上的訊息佇列產品不同的是,它沒有訊息佇列伺服器,而更像是一個網路通訊庫。從網路通訊的角度看,它處於會話層之上,應用程式層之下。【ZeroMQ 官網】:http://zeromq.org
ØMQ有4個基本通訊模型:分別是一對一結對模型(Exclusive-Pair)、請求回應模型(Request-Reply)、發布訂閱模型(Publish-Subscribe)、推拉模型(Push-Pull)。
Request-reply pattern 請求-回複模型
- 這種模型主要用於從用戶端向一個或多個服務執行個體發送請求,然後等待緊接著對於每個請求的回複
- 裡面又具體分了ZMQ_REQ ZMQ_REP ZMQ_DEALER ZMQ_ROUTER
- REQ 發送完訊息後,必須接收一個回應訊息後,才能發送新的訊息
- REP當接收訊息時,都會返回一個訊息
Publish-subscribe pattern 發布-訂閱模式
- 這種模式主要用於1對多的資料發布(一個發行者,多個訂閱者)
- 裡面又具體分了ZMQ_PUB ZMQ_SUB
- PUB發送訊息給所有的SUB。如果此時SUB沒有啟動,下次啟動時會漏掉該訊息
Pipeline pattern 管道模式
- 這種模式主要用於發布資料到由管道排列的節點上面,資料總是沿著管道流動。每個管道階段串連了至少一個節點
- 裡面又具體分了ZMQ_PUSH ZMQ_PULL
- 一個1對N隊列的實現,PUSH將資料放入隊列,PULL從隊列中不取出資料。資料會負載平衡的發送給每一個PULL
Exclusive pair pattern 獨立對模式
- peer to peer 模式。主要用於進程內部線程間通訊
- 裡面又具體分了ZMQ_PAIR
- 線程間1-to-1隊列的實現,採用了lock free實現,所以速度很快
下面是訂閱發布的範例程式碼:
發布服務端:
public static class NetMQPub { readonly static ManualResetEvent _terminateEvent = new ManualResetEvent(false); /// <summary> /// NetMQ 發布模式 /// </summary> public static void Start() { string[] wethers = new string[5] {"晴朗","多雲","陰天","小雨","暴雪" }; //CTRL+C 退出程式 Console.CancelKeyPress += Console_CancelKeyPress; Console.WriteLine("發布多個地區天氣預報:"); using (var context = NetMQContext.Create()) { using (var publisher = context.CreatePublisherSocket()) { publisher.Bind("tcp://127.0.0.1:5556"); var rng = new Random(); string msg; int sleeptime = 10; while (_terminateEvent.WaitOne(0) == false) { //隨機產生天氣資料 int zipcode = rng.Next(0, 99); int temperature = rng.Next(-50, 50); int wetherId = rng.Next(0, 4); msg = string.Format("{0} {1} {2}", zipcode, temperature, wethers[wetherId]); publisher.Send(msg,Encoding.UTF8, zmq.SendReceiveOptions.DontWait); Console.WriteLine(msg); Thread.Sleep(sleeptime); } } } } static void Console_CancelKeyPress(object sender, ConsoleCancelEventArgs e) { Console.WriteLine("exit..."); _terminateEvent.Set(); } }
訂閱用戶端,可啟動多個執行個體來類比接收天氣資訊:
public static class NetMQSub { public delegate void GetDataHandler(string message); public static event GetDataHandler OnGetData; /// <summary> /// NetMQ 訂閱模式 /// </summary> public static void Start() { var rng = new Random(); int zipcode = rng.Next(0, 99); Console.WriteLine("接收本地天氣預報 {0}...", zipcode); OnGetData += new GetDataHandler(ProcessData); using (var context = NetMQContext.Create()) using (var subscriber = context.CreateSubscriberSocket()) { subscriber.Connect("tcp://127.0.0.1:5556"); subscriber.Subscribe(zipcode.ToString(CultureInfo.InvariantCulture)); while(true) { string results = subscriber.ReceiveString(Encoding.UTF8); Console.Write("."); string[] split = results.Split(new[] { ‘ ‘ }, StringSplitOptions.RemoveEmptyEntries); int zip = int.Parse(split[0]); if (zip == zipcode) { OnGetData(results); } } } } public static void ProcessData(string msg) { Console.WriteLine("天氣情況:" + msg); } }
NetMQ發布訂閱C#樣本