ZEROMQ is the encapsulation of sockets, which enables complex network communication patterns by combining multiple types of nodes. and ZEROMQ design is simple, can have a variety of platform implementation, for cross-platform project is a gospel.
CLRZMQ is the implementation of the ZEROMQ C # language. When I was using CLRZMQ, I found that the server side of ZEROMQ, rep, replied to the message after receiving the message, but could not receive the message until the message was answered. The pseudo-code means that
while (true) { bytenewbyte[1024x768]; Receive (Receivedata); // Do some byte New byte [1024x768]; Send (Reponsedata);}
Since the name of ZEROMQ contains MQ (Message queue), it should have the function of the queue? The Router-dealer mode is described in the official manual of Zeromq:
Router can be used as a router, the role of caching messages, if the server is idle, the message will be sent through the dealer to the server.
This article implements the ZEROMQ message queue using C + +.
Fortunately, CLRZMQ has encapsulated the Router-dealer pattern and can use the Queuedevice class to achieve the same effect.
In my example, I put Router-dealer in the server process, dealer and server communication is county, interactive diagram as follows:
TCP inproc InProc connect ________________ Connect client I- ------------|router--------dealer| -----------Server-side ——————---------Queuedevice client code is as follows:
Static voidMain (string[] args) { stringServerAddress ="tcp://localhost:5555"; //ZMQ Context and client socket using(Zmqcontext context =zmqcontext.create ())using(Zmqsocket client =context. Createsocket (Sockettype.req)) {client. Connect (serveraddress); stringRequest ="Hello"; while(true)//for (int requestnum = 0; requestnum < requestnum++) { stringagain =Console.ReadLine (); Console.WriteLine ("Sending request ..."); Client. Send (Again+request, Encoding.unicode); stringReply =client. Receive (Encoding.unicode); Console.WriteLine ("Received reply {0}:", reply); } } }
Service-Side code:
classProgram {StaticZmqcontext context =zmqcontext.create (); StaticManualResetEvent _deviceready =NewManualResetEvent (false); //static ManualResetEvent _receiverready = new ManualResetEvent (false); Static voidMain (string[] args) {Startrouterdealer (); //ZMQ Context, server socket_deviceready.waitone (); using(Zmqsocket server =context. Createsocket (Sockettype.rep)) {//server. Bind ("InProc://backend ");Server. Connect ("Inproc://backend"); while(true) { //Wait for next request from client stringMessage =server. Receive (Encoding.unicode); Console.WriteLine ("Received Request: {0}", message); //ThreadPool.QueueUserWorkItem (New WaitCallback (procederequest), server); //Do Some ' work 'Thread.Sleep ( the); //Send reply back to clientserver. Send (message, encoding.unicode); } } } Private Static voidStartrouterdealer () {ThreadPool.QueueUserWorkItem (NewWaitCallback (Startqueuedevicethread),NULL); //ThreadPool.QueueUserWorkItem (New WaitCallback (startrouterdealerthread), null); } Private Static voidStartqueuedevicethread (ObjectState ) { //Thread.Sleep (+); using(Queuedevice queue =NewQueuedevice (Context,"tcp://*:5555", "Inproc://backend", devicemode.threaded)) {Queue. Initialize (); _deviceready.set (); Queue. Start (); while(true) {Thread.Sleep ( +); } } }
}
ZEROMQ's manual describes that Router-dealer must be started first, the server is restarted, so ManualResetEvent's role is to coordinate the boot sequence of the Queuedevice and the server.
Use ZEROMQ (CLRZMQ) for asynchronous communication