示例#1
0
        //
        // Load-balancing broker in C#
        //
        // Clients and workers are shown here in-process.
        // While this example runs in a single process, that is just to make
        // it easier to start and stop the example. Each thread may have its own
        // context and conceptually acts as a separate process.
        //
        // Author: metadings
        //

        // Basic request-reply client using REQ socket
        static void LBBroker_Client(ZContext context, int i)
        {
            // Create a socket
            using (var client = new ZSocket(context, ZSocketType.REQ))
            {
                // Set a printable identity
                client.IdentityString = "CLIENT" + i;

                // Connect
                client.Connect("inproc://frontend");

                using (var request = new ZMessage())
                {
                    request.Add(new ZFrame("Hello"));

                    // Send request
                    client.Send(request);
                }

                // Receive reply
                using (ZMessage reply = client.ReceiveMessage())
                {
                    reply.DumpZmsg("---Client received from broker---");

                    Console.WriteLine("CLIENT{0}: {1}", i, reply[0].ReadString());
                }
            }
        }
示例#2
0
			public void SendToBroker(string command, string option, ZMessage msg)
			{
				using (msg = msg != null ? msg.Duplicate() : new ZMessage())
				{
					if (!string.IsNullOrEmpty(option))
						msg.Prepend(new ZFrame(option));
					msg.Prepend(new ZFrame(command));
					msg.Prepend(new ZFrame(MdpCommon.MDPW_WORKER));
					msg.Prepend(new ZFrame(string.Empty));

					if (Verbose)
						msg.DumpZmsg("I: sending '{0:X}|{0}' to broker", command.ToMdCmd());

					Worker.Send(msg);
				}
			}
示例#3
0
        public void SendToBroker(string command, string option, ZMessage msg)
        {
            using (msg = msg != null ? msg.Duplicate() : new ZMessage())
            {
                if (!string.IsNullOrEmpty(option))
                {
                    msg.Prepend(new ZFrame(option));
                }
                msg.Prepend(new ZFrame(command));
                msg.Prepend(new ZFrame(MdpCommon.MDPW_WORKER));
                msg.Prepend(new ZFrame(string.Empty));

                if (Verbose)
                {
                    msg.DumpZmsg("I: sending '{0:X}|{0}' to broker", command.ToMdCmd());
                }

                Worker.Send(msg);
            }
        }
示例#4
0
        //  .until
        //  .skip
        //  The send method now just sends one message, without waiting for a
        //  reply. Since we're using a DEALER socket we have to send an empty
        //  frame at the start, to create the same envelope that the REQ socket
        //  would normally make for us:

        public int Send(string service, ZMessage request, CancellationTokenSource cancellor)
        {
            if (request == null)
            {
                throw new NotImplementedException();
            }

            if (cancellor.IsCancellationRequested ||
                (Console.KeyAvailable && Console.ReadKey(true).Key == ConsoleKey.Escape))
            {
                _context.Shutdown();
            }

            //  Prefix request with protocol frames
            //  Frame 0: empty (REQ emulation)
            //  Frame 1: "MDPCxy" (six bytes, MDP/Client x.y)
            //  Frame 2: Service name (printable string)
            request.Prepend(new ZFrame(service));
            request.Prepend(new ZFrame(MdpCommon.MDPC_CLIENT));
            request.Prepend(new ZFrame(string.Empty));

            if (Verbose)
            {
                request.DumpZmsg("I: send request to '{0}' service:", service);
            }

            ZError error;

            if (!Client.Send(request, out error))
            {
                ;
            }
            {
                if (Equals(error, ZError.ETERM))
                {
                    cancellor.Cancel(); // Interrupted
                }
                //throw new ZException(error);
            }
            return(0);
        }
示例#5
0
		public static void Identity(string[] args)
		{
			//
			// Demonstrate request-reply identities
			//
			// Author: metadings
			//

			using (var context = new ZContext())
			using (var sink = new ZSocket(context, ZSocketType.ROUTER))
			{
				sink.Bind("inproc://example");

				// First allow 0MQ to set the identity
				using (var anonymous = new ZSocket(context, ZSocketType.REQ))
				{
					anonymous.Connect("inproc://example");
					anonymous.Send(new ZFrame("ROUTER uses REQ's generated 5 byte identity"));
				}
				using (ZMessage msg = sink.ReceiveMessage())
				{    
					msg.DumpZmsg("--------------------------");
				}

				// Then set the identity ourselves
				using (var identified = new ZSocket(context, ZSocketType.REQ))
				{
					identified.IdentityString = "PEER2";
					identified.Connect("inproc://example");
					identified.Send(new ZFrame("ROUTER uses REQ's socket identity"));
				}
				using (ZMessage msg = sink.ReceiveMessage())
				{
					msg.DumpZmsg("--------------------------");
				}
			}
		}
示例#6
0
        //  .split worker send method
        //  This method formats and sends a command to a worker. The caller may
        //  also provide a command option, and a message payload:
        public void Send(string command, string option, ZMessage msg)
        {
            msg = msg != null
                    ? msg.Duplicate()
                    : new ZMessage();

            // Stack protocol envelope to start of message
            if (!string.IsNullOrEmpty(option))
            {
                msg.Prepend(new ZFrame(option));
            }
            msg.Prepend(new ZFrame(command));
            msg.Prepend(new ZFrame(MdpCommon.MDPW_WORKER));

            // Stack routing envelope to start of message
            msg.Wrap(Identity.Duplicate());

            if (Broker.Verbose)
            {
                msg.DumpZmsg("I: sending '{0:X}|{0}' to worker", command.ToMdCmd());
            }

            Broker.Socket.Send(msg);
        }
示例#7
0
        static void Main(string[] args)
        {
            //
            // Demonstrate request-reply identities
            //
            // Author: metadings
            //

            using (var context = new ZContext())
                using (var sink = new ZSocket(context, ZSocketType.ROUTER))
                {
                    sink.Bind("inproc://example");

                    // First allow 0MQ to set the identity
                    using (var anonymous = new ZSocket(context, ZSocketType.REQ))
                    {
                        anonymous.Connect("inproc://example");
                        anonymous.Send(new ZFrame("ROUTER uses REQ's generated 5 byte identity"));

                        ZMessage msg = sink.ReceiveMessage();
                        msg.DumpZmsg("-------------anonymous-------------");

                        using (msg)
                            using (ZMessage newMsg = new ZMessage())
                            {
                                //send three frame, but the client received is the only data frame, it's the 3rd frame.
                                newMsg.Add(msg[0]);
                                newMsg.Add(new ZFrame());
                                newMsg.Add(new ZFrame("router to REQ"));

                                sink.Send(newMsg);
                            }

                        using (ZMessage routerMsg = anonymous.ReceiveMessage())
                        {
                            routerMsg.DumpZmsg("-------------anonymous-------------");
                        }
                    }

                    // Then set the identity ourselves
                    using (var identified = new ZSocket(context, ZSocketType.REQ))
                    {
                        identified.IdentityString = "PEER2";
                        identified.Connect("inproc://example");
                        identified.Send(new ZFrame("ROUTER uses REQ's socket identity"));

                        ZMessage msg = sink.ReceiveMessage();
                        msg.DumpZmsg("------------identified--------------");

                        using (msg)
                            using (ZMessage newMsg = new ZMessage())
                            {
                                //send three frame, but the client received is the only data frame, it's the 3rd frame.
                                newMsg.Add(msg[0]);
                                //here, this is very important. If we do not add the empty frame, client will receive nothing.
                                newMsg.Add(new ZFrame());
                                newMsg.Add(new ZFrame("router to REQ"));

                                sink.Send(newMsg);
                            }

                        using (ZMessage routerMsg = identified.ReceiveMessage())
                        {
                            routerMsg.DumpZmsg("-------------identified-------------");
                        }
                    }

                    using (var DEALERIdentify = new ZSocket(context, ZSocketType.DEALER))
                    {
                        DEALERIdentify.Connect("inproc://example");
                        DEALERIdentify.Send(new ZFrame("ROUTER uses Dealer's generated 5 byte identity, But there is no empty frame as separeator"));

                        ZMessage msg = sink.ReceiveMessage();
                        msg.DumpZmsg("------------DEALERIdentify--------------");

                        using (msg)
                            using (ZMessage newMsg = new ZMessage())
                            {
                                //send three frame, but the client received is the only data frame, it's the 3rd frame.
                                newMsg.Add(msg[0]);
                                //here, this is very important. That there is no separeator for Dealer!!!!!!!!!!!!!!, If we add the empty frame, it will be treat as data frame
                                //newMsg.Add(new ZFrame());
                                newMsg.Add(new ZFrame("router to REQ"));

                                sink.Send(newMsg);
                            }

                        using (ZMessage routerMsg = DEALERIdentify.ReceiveMessage())
                        {
                            routerMsg.DumpZmsg("-------------DEALERIdentify-------------");
                        }
                    }
                }

            Console.WriteLine();
            Console.WriteLine("Press any key to exit...");
            Console.ReadLine();
        }
示例#8
0
            //  .split worker send method
            //  This method formats and sends a command to a worker. The caller may
            //  also provide a command option, and a message payload:
            public void Send(string command, string option, ZMessage msg)
            {
                msg = msg != null
                        ? msg.Duplicate()
                        : new ZMessage();

                // Stack protocol envelope to start of message
                if (!string.IsNullOrEmpty(option))
                    msg.Prepend(new ZFrame(option));
                msg.Prepend(new ZFrame(command));
                msg.Prepend(new ZFrame(MdpCommon.MDPW_WORKER));

                // Stack routing envelope to start of message
                msg.Wrap(Identity.Duplicate());

                if(Broker.Verbose)
                    msg.DumpZmsg("I: sending '{0:X}|{0}' to worker", command.ToMdCmd());

                Broker.Socket.Send(msg);
            }
示例#9
0
            //  .split broker worker_msg method
            //  This method processes one READY, REPLY, HEARTBEAT, or
            //  DISCONNECT message sent to the broker by a worker:
            public void WorkerMsg(ZFrame sender, ZMessage msg)
            {
                if(msg.Count < 1) // At least, command
                    throw new InvalidOperationException();

                ZFrame command = msg.Pop();
                //string id_string = sender.ReadString();
                bool isWorkerReady;
                //string id_string;
                using (var sfrm = sender.Duplicate())
                {
                    var idString = sfrm.Read().ToHexString();
                    isWorkerReady = Workers.ContainsKey(idString);
                }
                Worker worker = RequireWorker(sender);
                using (msg)
                using (command)
                {
                    if (command.StrHexEq(MdpCommon.MdpwCmd.READY))
                    {
                        if (isWorkerReady)
                            // Not first command in session
                            worker.Delete(true);
                        else if (command.Length >= 4
                              && command.ToString().StartsWith("mmi."))
                            // Reserd servicee name
                            worker.Delete(true);
                        else
                        {
                            // Attach worker to service and mark as idle
                            using (ZFrame serviceFrame = msg.Pop())
                            {
                                worker.Service = RequireService(serviceFrame);
                                worker.Service.Workers++;
                                worker.Waiting();
                            }
                        }
                    }
                    else if (command.StrHexEq(MdpCommon.MdpwCmd.REPLY))
                    {
                        if (isWorkerReady)
                        {
                            //  Remove and save client return envelope and insert the
                            //  protocol header and service name, then rewrap envelope.
                            ZFrame client = msg.Unwrap();
                            msg.Prepend(new ZFrame(worker.Service.Name));
                            msg.Prepend(new ZFrame(MdpCommon.MDPC_CLIENT));
                            msg.Wrap(client);
                            Socket.Send(msg);
                            worker.Waiting();
                        }
                        else
                        {
                            worker.Delete(true);
                        }
                    }
                    else if (command.StrHexEq(MdpCommon.MdpwCmd.HEARTBEAT))
                    {
                        if (isWorkerReady)
                        {
                            worker.Expiry = DateTime.UtcNow + MdpCommon.HEARTBEAT_EXPIRY;
                        }
                        else
                        {
                            worker.Delete(true);
                        }
                    }
                    else if (command.StrHexEq(MdpCommon.MdpwCmd.DISCONNECT))
                        worker.Delete(false);
                    else
                    {
                        msg.DumpZmsg("E: invalid input message");
                    }
                }
            }
示例#10
0
            //  .split send request and wait for reply
            //  Here is the {{send}} method. It sends a request to the broker and gets
            //  a reply even if it has to retry several times. It takes ownership of
            //  the request message, and destroys it when sent. It returns the reply
            //  message, or NULL if there was no reply after multiple attempts:
            public ZMessage Send(string service, ZMessage request, CancellationTokenSource cancellor)
            {
                if (request == null)
                {
                    throw new InvalidOperationException();
                }

                //  Prefix request with protocol frames
                //  Frame 1: "MDPCxy" (six bytes, MDP/Client x.y)
                //  Frame 2: Service name (printable string)
                request.Prepend(new ZFrame(service));
                request.Prepend(new ZFrame(MdpCommon.MDPC_CLIENT));
                if (Verbose)
                {
                    request.DumpZmsg("I: send request to '{0}' service:", service);
                }

                int retriesLeft = Retries;

                while (retriesLeft > 0 && !cancellor.IsCancellationRequested)
                {
                    if (cancellor.IsCancellationRequested ||
                        (Console.KeyAvailable && Console.ReadKey(true).Key == ConsoleKey.Escape))
                    {
                        _context.Shutdown();
                    }

                    // Copy the Request and send on Client
                    ZMessage msgreq = request.Duplicate();

                    ZError error;
                    if (!Client.Send(msgreq, out error))
                    {
                        if (Equals(error, ZError.ETERM))
                        {
                            cancellor.Cancel();
                            break; // Interrupted
                        }
                    }

                    var      p = ZPollItem.CreateReceiver();
                    ZMessage msg;
                    //  .split body of send
                    //  On any blocking call, {{libzmq}} will return -1 if there was
                    //  an error; we could in theory check for different error codes,
                    //  but in practice it's OK to assume it was {{EINTR}} (Ctrl-C):

                    // Poll the client Message
                    if (Client.PollIn(p, out msg, out error, Timeout))
                    {
                        //  If we got a reply, process it
                        if (Verbose)
                        {
                            msg.DumpZmsg("I: received reply");
                        }

                        if (msg.Count < 3)
                        {
                            throw new InvalidOperationException();
                        }

                        using (ZFrame header = msg.Pop())
                            if (!header.ToString().Equals(MdpCommon.MDPC_CLIENT))
                            {
                                throw new InvalidOperationException();
                            }

                        using (ZFrame replyService = msg.Pop())
                            if (!replyService.ToString().Equals(service))
                            {
                                throw new InvalidOperationException();
                            }

                        request.Dispose();
                        return(msg);
                    }
                    else if (Equals(error, ZError.ETERM))
                    {
                        cancellor.Cancel();
                        break; // Interrupted
                    }
                    else if (Equals(error, ZError.EAGAIN))
                    {
                        if (--retriesLeft > 0)
                        {
                            if (Verbose)
                            {
                                "W: no reply, reconnecting...".DumpString();
                            }

                            ConnectToBroker();
                        }
                        else
                        {
                            if (Verbose)
                            {
                                "W: permanent error, abandoning".DumpString();
                            }
                            break; // Give up
                        }
                    }
                }
                if (cancellor.IsCancellationRequested)
                {
                    "W: interrupt received, killing client...\n".DumpString();
                }
                request.Dispose();
                return(null);
            }
示例#11
0
            //  .split send request and wait for reply
            //  Here is the {{send}} method. It sends a request to the broker and gets
            //  a reply even if it has to retry several times. It takes ownership of 
            //  the request message, and destroys it when sent. It returns the reply
            //  message, or NULL if there was no reply after multiple attempts:
            public ZMessage Send(string service, ZMessage request, CancellationTokenSource cancellor)
            {
                if (request == null)
                    throw new InvalidOperationException();

                //  Prefix request with protocol frames
                //  Frame 1: "MDPCxy" (six bytes, MDP/Client x.y)
                //  Frame 2: Service name (printable string)
                request.Prepend(new ZFrame(service));
                request.Prepend(new ZFrame(MdpCommon.MDPC_CLIENT));
                if (Verbose)
                    request.DumpZmsg("I: send request to '{0}' service:", service);

                int retriesLeft = Retries;
                while (retriesLeft > 0 && !cancellor.IsCancellationRequested)
                {
                    if (cancellor.IsCancellationRequested
                        || (Console.KeyAvailable && Console.ReadKey(true).Key == ConsoleKey.Escape))
                        _context.Shutdown();

                    // Copy the Request and send on Client
                    ZMessage msgreq = request.Duplicate();

                    ZError error;
                    if (!Client.Send(msgreq, out error))
                    {
                        if (Equals(error, ZError.ETERM))
                        {
                            cancellor.Cancel();
                            break; // Interrupted
                        }
                    }

                    var p = ZPollItem.CreateReceiver();
                    ZMessage msg;
                    //  .split body of send 
                    //  On any blocking call, {{libzmq}} will return -1 if there was
                    //  an error; we could in theory check for different error codes,
                    //  but in practice it's OK to assume it was {{EINTR}} (Ctrl-C):

                    // Poll the client Message
                    if (Client.PollIn(p, out msg, out error, Timeout))
                    {
                        //  If we got a reply, process it
                        if (Verbose)
                            msg.DumpZmsg("I: received reply");

                        if(msg.Count < 3)
                            throw new InvalidOperationException();

                        using (ZFrame header = msg.Pop())
                            if (!header.ToString().Equals(MdpCommon.MDPC_CLIENT))
                                throw new InvalidOperationException();

                        using (ZFrame replyService = msg.Pop())
                            if(!replyService.ToString().Equals(service))
                                throw new InvalidOperationException();

                        request.Dispose();
                        return msg;
                    }
                    else if (Equals(error, ZError.ETERM))
                    {
                        cancellor.Cancel();
                        break; // Interrupted
                    }
                    else if (Equals(error, ZError.EAGAIN))
                    {
                        if (--retriesLeft > 0)
                        {
                            if (Verbose)
                                "W: no reply, reconnecting...".DumpString();

                            ConnectToBroker();
                        }
                        else
                        {
                            if (Verbose)
                                "W: permanent error, abandoning".DumpString();
                            break; // Give up
                        }
                    }
                }
                if (cancellor.IsCancellationRequested)
                {
                    "W: interrupt received, killing client...\n".DumpString();
                }
                request.Dispose();
                return null;
            }
示例#12
0
            //  .split broker worker_msg method
            //  This method processes one READY, REPLY, HEARTBEAT, or
            //  DISCONNECT message sent to the broker by a worker:
            public void WorkerMsg(ZFrame sender, ZMessage msg)
            {
                if (msg.Count < 1) // At least, command
                {
                    throw new InvalidOperationException();
                }

                ZFrame command = msg.Pop();
                //string id_string = sender.ReadString();
                bool isWorkerReady;

                //string id_string;
                using (var sfrm = sender.Duplicate())
                {
                    var idString = sfrm.Read().ToHexString();
                    isWorkerReady = Workers.ContainsKey(idString);
                }
                Worker worker = RequireWorker(sender);

                using (msg)
                    using (command)
                    {
                        if (command.StrHexEq(MdpCommon.MdpwCmd.READY))
                        {
                            if (isWorkerReady)
                            {
                                // Not first command in session
                                worker.Delete(true);
                            }
                            else if (command.Length >= 4 &&
                                     command.ToString().StartsWith("mmi."))
                            {
                                // Reserd servicee name
                                worker.Delete(true);
                            }
                            else
                            {
                                // Attach worker to service and mark as idle
                                using (ZFrame serviceFrame = msg.Pop())
                                {
                                    worker.Service = RequireService(serviceFrame);
                                    worker.Service.Workers++;
                                    worker.Waiting();
                                }
                            }
                        }
                        else if (command.StrHexEq(MdpCommon.MdpwCmd.REPLY))
                        {
                            if (isWorkerReady)
                            {
                                //  Remove and save client return envelope and insert the
                                //  protocol header and service name, then rewrap envelope.
                                ZFrame client = msg.Unwrap();
                                msg.Prepend(new ZFrame(worker.Service.Name));
                                msg.Prepend(new ZFrame(MdpCommon.MDPC_CLIENT));
                                msg.Wrap(client);
                                Socket.Send(msg);
                                worker.Waiting();
                            }
                            else
                            {
                                worker.Delete(true);
                            }
                        }
                        else if (command.StrHexEq(MdpCommon.MdpwCmd.HEARTBEAT))
                        {
                            if (isWorkerReady)
                            {
                                worker.Expiry = DateTime.UtcNow + MdpCommon.HEARTBEAT_EXPIRY;
                            }
                            else
                            {
                                worker.Delete(true);
                            }
                        }
                        else if (command.StrHexEq(MdpCommon.MdpwCmd.DISCONNECT))
                        {
                            worker.Delete(false);
                        }
                        else
                        {
                            msg.DumpZmsg("E: invalid input message");
                        }
                    }
            }
示例#13
0
            //  .until
            //  .skip
            //  The send method now just sends one message, without waiting for a
            //  reply. Since we're using a DEALER socket we have to send an empty
            //  frame at the start, to create the same envelope that the REQ socket
            //  would normally make for us:

            public int Send(string service, ZMessage request, CancellationTokenSource cancellor)
            {
                if (request == null)
                    throw new NotImplementedException();

                if (cancellor.IsCancellationRequested
                        || (Console.KeyAvailable && Console.ReadKey(true).Key == ConsoleKey.Escape))
                    _context.Shutdown();

                //  Prefix request with protocol frames
                //  Frame 0: empty (REQ emulation)
                //  Frame 1: "MDPCxy" (six bytes, MDP/Client x.y)
                //  Frame 2: Service name (printable string)
                request.Prepend(new ZFrame(service));
                request.Prepend(new ZFrame(MdpCommon.MDPC_CLIENT));
                request.Prepend(new ZFrame(string.Empty));

                if (Verbose)
                    request.DumpZmsg("I: send request to '{0}' service:", service);

                ZError error; 
                if(!Client.Send(request, out error));
                {
                    if (Equals(error, ZError.ETERM))
                        cancellor.Cancel(); // Interrupted
                    //throw new ZException(error);
                }
                return 0;
            }