コード例 #1
0
ファイル: espresso.cs プロジェクト: 09130510/zguide
		static void Espresso_Publisher(ZContext context) 
		{
			// The publisher sends random messages starting with A-J:

			using (var publisher = new ZSocket(context, ZSocketType.PUB))
			{
				publisher.Bind("tcp://*:6000");

				ZError error;

				while (true)
				{
					var bytes = new byte[5];
					using (var rng = new System.Security.Cryptography.RNGCryptoServiceProvider())
					{
						rng.GetBytes(bytes);
					}
					var frame = new ZFrame(bytes);
					if (!publisher.Send(frame, out error))
					{
						if (error == ZError.ETERM)
							return;	// Interrupted
						throw new ZException(error);
					}

					Thread.Sleep(1);
				}
			}
		}
コード例 #2
0
ファイル: ZFrame.cs プロジェクト: Giten2004/clrzmq4
        public ZFrame Duplicate()
        {
            var frame = ZFrame.CreateEmpty();

            this.CopyZeroTo(frame);
            return(frame);
        }
コード例 #3
0
ファイル: Program.cs プロジェクト: ray-zong/zguide
		static void Console_WriteZFrame(string format, ZFrame frame, params object[] data)
		{
			var renderer = new StringBuilder();

			var list = new List<object>(data);

			// here the renderer

			renderer.Append(format);
			renderer.Append(": ");
			renderer.Append("{");
			renderer.Append(0 + data.Length);
			renderer.Append("}");

			// now the message

			frame.Position = 0;

			if (frame.Length == 0)
				list.Add("0");
			else
				list.Add(frame.ReadString());

			frame.Position = 0;

			Console.WriteLine(renderer.ToString(), list.ToArray());
		}
コード例 #4
0
ファイル: ZSocket.cs プロジェクト: zmapi/ctst4-acmd
        public virtual bool SendFrame(ZFrame frame, ZSocketFlags flags, out ZError error)
        {
            EnsureNotDisposed();

            if (frame.IsDismissed)
            {
                throw new ObjectDisposedException("frame");
            }

            error = default(ZError);

            while (-1 == zmq.msg_send(frame.Ptr, _socketPtr, (int)flags))
            {
                error = ZError.GetLastErr();

                if (error == ZError.EINTR)
                {
                    error = default(ZError);
                    continue;
                }

                return(false);
            }

            // Tell IDisposable to not unallocate zmq_msg
            frame.Dismiss();
            return(true);
        }
コード例 #5
0
ファイル: Program.cs プロジェクト: sixeyed/handling-failures
        private static void Handle(Header header, ZFrame bodyFrame)
        {
            //TODO - really we'd have a message handler factory:
            if (header.BodyType == typeof(SendFulfilmentCommand).Name)
            {
                var command = JsonConvert.DeserializeObject<SendFulfilmentCommand>(bodyFrame.ReadString());
                var client = FulfilmentClientFactory.GetApiClient(command.FulfilmentType);
                try
                {
                    client.Send(command.Address);
                    Console.WriteLine("*** Sent fulfilment, type: {0}, to address: {1}", command.FulfilmentType, command.Address);
                }
                catch (Exception ex)
                {
                    Console.WriteLine("*** Fulfilment failed, resending message");

                    var queueAddress = Config.Get("Queues.Fulfilment.Address");
                    header.HandledCount++;
                    header.LastExceptionMessage = ex.Message;

                    var messageFrames = new List<ZFrame>();
                    messageFrames.Add(new ZFrame(JsonConvert.SerializeObject(header)));
                    messageFrames.Add(bodyFrame);

                    using (var context = new ZContext())
                    using (var sender = new ZSocket(context, ZSocketType.PUSH))
                    {
                        sender.Connect(queueAddress);
                        sender.Send(new ZMessage(messageFrames));
                    }
                }
            }
        }
コード例 #6
0
ファイル: flclient1.cs プロジェクト: ray-zong/zguide
		static ZFrame FLClient1_TryRequest(ZContext context, string endpoint, ZFrame request)
		{
			Console.WriteLine("I: trying echo service at {0}...", endpoint);

			using (var client = new ZSocket(context, ZSocketType.REQ))
			{
				client.Connect(endpoint);

				// Send request, wait safely for reply
				using (var message = ZFrame.CopyFrom(request))
				{
					client.Send(message);
				}

				var poll = ZPollItem.CreateReceiver();
				ZError error;
				ZMessage incoming;

				if (client.PollIn(poll, out incoming, out error, FLClient1_REQUEST_TIMEOUT))
				{
					return incoming[0];
				}
			}
			return null;
		}
コード例 #7
0
ファイル: ZFrame.cs プロジェクト: sanjay-ns/clrzmq4
        public static ZFrame FromStream(Stream stream, long i, int l)
        {
            stream.Position = i;
            if (l == 0)
            {
                return(new ZFrame());
            }

            var frame = ZFrame.Create(l);
            var buf = new byte[65535];
            int bufLen, remaining, current = -1;

            do
            {
                ++current;
                remaining = Math.Min(Math.Max(0, l - current * buf.Length), buf.Length);
                if (remaining < 1)
                {
                    break;
                }

                bufLen = stream.Read(buf, 0, remaining);
                frame.Write(buf, 0, bufLen);
            } while (bufLen > 0);

            frame.Position = 0;
            return(frame);
        }
コード例 #8
0
ファイル: BaseZMQWorker.cs プロジェクト: cosmosbox/cosmos
        void MainLoop(object obj)
        {
            using (var outgoing = new ZFrame("READY"))
            {
                workerSocket.Send(outgoing);
            }

            ZError error;
            ZMessage incoming;
            var poll = ZPollItem.CreateReceiver();
            while (true)
            {
                while (true)
                {
                    var result = workerSocket.PollIn(poll, out incoming, out error, TimeSpan.FromMilliseconds(1));
                    if (!result)
                    {
                        if (error == ZError.EAGAIN)
                        {
                            //await Task.Delay(1);
                            //yield return null;
                            continue;
                        }
                        if (error == ZError.ETERM)
                        {
                            Logger.Error("ETERM!");
                            return; // Interrupted
                            //yield break;
                        }
                        throw new ZException(error);
                    }
                    else
                    {
                        using (incoming)
                        {
                            // Send message back
                            //worker.Send(incoming);
                            _server.OnRecvMsg(this, incoming);
                            break;
                        }
                    }
                }
                //if (null == (incoming = workerSocket.ReceiveMessage(out error)))
                //{
                //    if (error == ZError.ETERM)
                //        return;

                //    throw new ZException(error);
                //}

                //using (incoming)
                //{
                //    // Send message back
                //    //worker.Send(incoming);
                //    _server.OnRecvMsg(this, incoming);

                //}
            }
        }
コード例 #9
0
ファイル: ppqueue.cs プロジェクト: ChenXuJasper/zguide
			// Construct new worker
			public Worker(ZFrame identity) 
			{
				Identity = identity;

				this.Expiry = DateTime.UtcNow + TimeSpan.FromMilliseconds(
					PPP_HEARTBEAT_INTERVAL.Milliseconds * PPP_HEARTBEAT_LIVENESS
				);
			}
コード例 #10
0
ファイル: ZSocket.cs プロジェクト: zmapi/ctst4-acmd
        public virtual void SendFrame(ZFrame frame, ZSocketFlags flags)
        {
            ZError error;

            if (!SendFrame(frame, flags, out error))
            {
                throw new ZException(error);
            }
        }
コード例 #11
0
ファイル: lbbroker.cs プロジェクト: ray-zong/zguide
		static void LBBroker_Worker(ZContext context, int i)
		{
			// This is the worker task, using a REQ socket to do load-balancing.

			// Create socket
			using (var worker = new ZSocket(context, ZSocketType.REQ))
			{
				// Set a printable identity
				worker.IdentityString = "WORKER" + i;

				// Connect
				worker.Connect("inproc://backend");

				// Tell broker we're ready for work
				using (var ready = new ZFrame("READY"))
				{
					worker.Send(ready);
				}

				ZError error;
				ZMessage request;

				while (true)
				{
					// Get request
					if (null == (request = worker.ReceiveMessage(out error)))
					{
						// We are using "out error",
						// to NOT throw a ZException ETERM
						if (error == ZError.ETERM)
							break;

						throw new ZException(error);
					}

					using (request)
					{
						string worker_id = request[0].ReadString();

						string requestText = request[2].ReadString();
						Console.WriteLine("WORKER{0}: {1}", i, requestText);

						// Send reply
						using (var commit = new ZMessage())
						{
							commit.Add(new ZFrame(worker_id));
							commit.Add(new ZFrame());
							commit.Add(new ZFrame("OK"));

							worker.Send(commit);
						}
					}
				}
			}
		}
コード例 #12
0
ファイル: ZSocket.cs プロジェクト: zmapi/ctst4-acmd
        }         // just Send*

        public ZFrame ReceiveFrame()
        {
            ZError error;
            ZFrame frame = ReceiveFrame(out error);

            if (error != ZError.None)
            {
                throw new ZException(error);
            }
            return(frame);
        }
コード例 #13
0
ファイル: ppqueue.cs プロジェクト: ChenXuJasper/zguide
			protected void Dispose(bool disposing)
			{
				if (disposing)
				{
					if (Identity != null)
					{
						Identity.Dispose();
						Identity = null;
					}
				}
			}
コード例 #14
0
        static bool ReceiveMsg(ZSocket sock, ref ZMessage message, out string address, out ZError error)
        {
            error = ZError.None;
            // address = IPAddress.None;
            address = string.Empty;

            // STREAM: read frames: identity, body

            // read the ip4 address from (ZFrame)frame.GetOption("Peer-Address")

            int receiveCount = 2;

            do
            {
                var frame = ZFrame.CreateEmpty();

                while (-1 == zmq.msg_recv(frame.Ptr, sock.SocketPtr, (int)(/* ZSocketFlags.DontWait | */ ZSocketFlags.More)))
                {
                    error = ZError.GetLastErr();

                    if (error == ZError.EINTR)
                    {
                        error = default(ZError);
                        continue;
                    }

                    frame.Dispose();
                    return(false);
                }

                if (message == null)
                {
                    message = new ZMessage();
                }
                message.Add(frame);

                if (receiveCount == 2)
                {
                    if (default(string) == (address = frame.GetOption("Peer-Address", out error)))
                    {
                        // just ignore
                        error   = default(ZError);
                        address = string.Empty;
                    }
                }
            } while (--receiveCount > 0);

            return(true);
        }
コード例 #15
0
        public static ZFrame FromStream(Stream stream, long i, int l)
        {
            stream.Position = i;
            if (l == 0)
            {
                return(new ZFrame());
            }

            var frame = ZFrame.Create(l);

            stream.CopyTo(frame);
            frame.Position = 0;

            return(frame);
        }
コード例 #16
0
ファイル: tripping.cs プロジェクト: ChenXuJasper/zguide
        static void Tripping_ClientTask(ZContext ctx, ZSocket pipe, CancellationTokenSource cancellor, object[] args)
        {
            using (ZSocket client = new ZSocket(ctx, ZSocketType.DEALER))
            {
                client.Connect("tcp://127.0.0.1:5555");
                "Setting up test...".DumpString();
                Thread.Sleep(100);

                int requests;
                "Synchronous round-trip test...".DumpString();
                var start = DateTime.Now;
                Stopwatch sw = Stopwatch.StartNew();
                for (requests = 0; requests < 10000; requests++)
                {
                    using (var outgoing = new ZFrame("hello"))
                    {
                        client.Send(outgoing);
                        using (var reply = client.ReceiveFrame())
                        {
                            if (Verbose)
                                reply.ToString().DumpString();
                        }
                    }
                }
                sw.Stop();
                " {0} calls - {1} ms => {2} calls / second".DumpString(requests, sw.ElapsedMilliseconds, requests * 1000 / sw.ElapsedMilliseconds);

                "Asynchronous round-trip test...".DumpString();
                sw.Restart();
                // sending 100000 requests => often ends in eagain exception in ZContext.Proxy!!
                for (requests = 0; requests < 1000; requests++)
                    using (var outgoing = new ZFrame("hello"))
                        client.SendFrame(outgoing);

                for (requests = 0; requests < 1000; requests++)
                    using (var reply = client.ReceiveFrame())
                        if (Verbose)
                            reply.ToString().DumpString();
                sw.Stop();
                " {0} calls - {1} ms => {2} calls / second".DumpString(requests, sw.ElapsedMilliseconds, requests * 1000 / sw.ElapsedMilliseconds);
                using (var outgoing = new ZFrame("done"))
                    pipe.SendFrame(outgoing);
            }
        }
コード例 #17
0
ファイル: wuserver.cs プロジェクト: ChenXuJasper/zguide
		public static void WUServer(string[] args)
		{
			//
			// Weather update server
			// Binds PUB socket to tcp://*:5556
			// Publishes random weather updates
			//
			// Author: metadings
			//

			// Prepare our context and publisher
			using (var context = new ZContext())
			using (var publisher = new ZSocket(context, ZSocketType.PUB))
			{
				string address = "tcp://*:5556";
				Console.WriteLine("I: Publisher.Bind'ing on {0}", address);
				publisher.Bind(address);

				/* foreach (IPAddress localAddress in WUProxy_GetPublicIPs())
				{
					var epgmAddress = string.Format("epgm://{0};239.192.1.1:8100", localAddress);
					Console.WriteLine("I: Publisher.Bind'ing on {0}...", epgmAddress);
					publisher.Bind(epgmAddress);
				} */

				// Initialize random number generator
				var rnd = new Random();

				while (true)
				{
					// Get values that will fool the boss
					int zipcode = rnd.Next(99999);
					int temperature = rnd.Next(-55, +45);

					// Send message to all subscribers
					var update = string.Format("{0:D5} {1}", zipcode, temperature);
					using (var updateFrame = new ZFrame(update))
					{
						publisher.Send(updateFrame);
					}
				}
			}
		}
コード例 #18
0
ファイル: Program.cs プロジェクト: dshaneg/zmqpoc
        private static void _Publish(ZContext context, string alias)
        {
            using (var broadcaster = new ZSocket(context, ZSocketType.PUB))
            {
                const string address = "tcp://*:9000";
                Console.WriteLine("Binding on {0}", address);
                broadcaster.Bind(address);

                while (true)
                {
                    var message = Console.ReadLine();

                    using (var sendFrame = new ZFrame(string.Format("{0}: {1}", alias, message)))
                    {
                        broadcaster.Send(sendFrame);
                    }
                }
            }
        }
コード例 #19
0
ファイル: eagain.cs プロジェクト: ray-zong/zguide
		public static void EAgain(string[] args)
		{
			//
			// Shows how to provoke EAGAIN when reaching HWM
			//
			// Author: metadings
			//

			using (var context = new ZContext())
			using (var mailbox = new ZSocket(context, ZSocketType.DEALER))
			{
				mailbox.SendHighWatermark = 4;
				mailbox.SendTimeout = TimeSpan.Zero;
				mailbox.Linger = TimeSpan.Zero;
				mailbox.Connect("tcp://127.0.0.1:9876");

				ZError error;
				for (int count = 0; count < 10; ++count)
				{
					Console.WriteLine("Sending {0}. message", count);

					using (var outgoing = new ZFrame(string.Format("message {0}", count)))
					{
						if (!mailbox.Send(outgoing, ZSocketFlags.DontWait, out error))
						{
							if (error == ZError.EAGAIN)
							{
								Console.WriteLine(new ZException(error));
								break;

								/* Usually when reaching EAGAIN, I would do
								Thread.Sleep(1);
								continue; /**/
							}
							if (error == ZError.ETERM)
								return;	// Interrupted
							throw new ZException(error);
						}
					}
				}
			}
		}
コード例 #20
0
ファイル: ZFrame.cs プロジェクト: zhangwenquan/clrzmq4
        public void CopyZeroTo(ZFrame other)
        {
            // zmq.msg_copy(dest, src)
            ZError error;

            while (-1 == zmq.msg_copy(other.framePtr, framePtr))
            {
                error = ZError.GetLastErr();

                if (error == ZError.EINTR)
                {
                    error = default(ZError);
                    continue;
                }
                if (error == ZError.EFAULT)
                {
                    // Invalid message.
                }
                throw new ZException(error, "zmq_msg_copy");
            }
        }
コード例 #21
0
ファイル: ZSocket.cs プロジェクト: zmapi/ctst4-acmd
        public bool ReceiveFrames <ListT>(ref int framesToReceive, ref ListT frames, ZSocketFlags flags, out ZError error)
            where ListT : IList <ZFrame>, new()
        {
            EnsureNotDisposed();

            error = default(ZError);
            flags = flags | ZSocketFlags.More;

            do
            {
                var frame = ZFrame.CreateEmpty();

                if (framesToReceive == 1)
                {
                    flags = flags & ~ZSocketFlags.More;
                }

                while (-1 == zmq.msg_recv(frame.Ptr, _socketPtr, (int)flags))
                {
                    error = ZError.GetLastErr();

                    if (error == ZError.EINTR)
                    {
                        error = default(ZError);
                        continue;
                    }

                    frame.Dispose();
                    return(false);
                }

                if (frames == null)
                {
                    frames = new ListT();
                }
                frames.Add(frame);
            } while (--framesToReceive > 0 && this.ReceiveMore);

            return(true);
        }
コード例 #22
0
ファイル: peering2.cs プロジェクト: ray-zong/zguide
		static void Peering2_ClientTask(ZContext context, int i, string name, string message) 
		{
			// The client task does a request-reply dialog
			// using a standard synchronous REQ socket

			using (var client = new ZSocket(context, ZSocketType.REQ))
			{
				// Set printable identity
				client.IdentityString = name;

				// Connect
				client.Connect("tcp://127.0.0.1:" + Peering2_GetPort(name) + 1);

				ZError error;

				while (true)
				{
					// Send
					using (var outgoing = new ZFrame(message))
					{
						client.Send(outgoing);
					}

					// Receive
					ZFrame incoming = client.ReceiveFrame(out error);

					if (incoming == null)
					{
						if (error == ZError.ETERM)
							return;	// Interrupted

						throw new ZException(error);
					}
					using (incoming)
					{
						Console.WriteLine("Client {0}: {1}", name, incoming.ReadString());
					}
				}
			}
		}
コード例 #23
0
        /// <summary>
        /// Forwards replies from the backend socket to the frontend socket.
        /// </summary>
        protected override bool BackendHandler(ZSocket sock, out ZMessage message, out ZError error)
        {
            error   = default(ZError);
            message = null;

            // receiving scope
            // DEALER: normal movemsg
            ZMessage incoming = null;

            if (!sock.ReceiveMessage(ref incoming, /* ZSocketFlags.DontWait */ ZSocketFlags.None, out error))
            {
                return(false);
            }

            using (incoming)
            {
                // STREAM: write frames: identity, body, identity, empty
                // Read identity
                int ic            = (int)incoming[0].Length;
                var identityBytes = new byte[ic];
                incoming[0].Read(identityBytes, 0, ic);

                // Remove DEALER's delimiter
                incoming.RemoveAt(1);

                // Append Identity frame
                var identity0 = new ZFrame(identityBytes);
                incoming.Add(identity0);

                // Append STREAM's empty delimiter frame
                incoming.Add(new ZFrame());

                if (!SendMsg(FrontendSocket, incoming, out error))
                {
                    return(false);
                }
            }

            return(true);
        }
コード例 #24
0
        internal void BindConnect()
        {
            foreach (string endpoint in _bindings)
            {
                _socket.Bind(endpoint);
            }

            foreach (string endpoint in _connections)
            {
                _socket.Connect(endpoint);
            }

            if (_subscription != null)
            {
                // _socket.Subscribe(_subscription);

                using (var subscription = new ZFrame(_subscription))
                {
                    _socket.Send(subscription);
                }
            }
        }
コード例 #25
0
ファイル: ppworker.cs プロジェクト: ChenXuJasper/zguide
		static ZSocket PPWorker_CreateZSocket(ZContext context, string name, out ZError error)
		{
			// Helper function that returns a new configured socket
			// connected to the Paranoid Pirate queue

			var worker = new ZSocket(context, ZSocketType.DEALER);
			worker.IdentityString = name;

			if (!worker.Connect("tcp://127.0.0.1:5556", out error))
			{
				return null;	// Interrupted
			}

			// Tell queue we're ready for work
			using (var outgoing = new ZFrame(Worker.PPP_READY))
			{
				worker.Send(outgoing);
			}

			Console.WriteLine("I:        worker ready");
			return worker;
		}
コード例 #26
0
ファイル: ZSocket.cs プロジェクト: zmapi/ctst4-acmd
        public virtual bool SendFrames(IEnumerable <ZFrame> frames, ref int sent, ZSocketFlags flags, out ZError error)
        {
            EnsureNotDisposed();

            error = ZError.None;

            bool more = (flags & ZSocketFlags.More) == ZSocketFlags.More;

            flags = flags | ZSocketFlags.More;

            bool framesIsList = frames is IList <ZFrame>;

            ZFrame[] _frames = frames.ToArray();

            for (int i = 0, l = _frames.Length; i < l; ++i)
            {
                ZFrame frame = _frames[i];

                if (i == l - 1 && !more)
                {
                    flags = flags & ~ZSocketFlags.More;
                }

                if (!SendFrame(frame, flags, out error))
                {
                    return(false);
                }

                if (framesIsList)
                {
                    ((IList <ZFrame>)frames).Remove(frame);
                }

                ++sent;
            }

            return(true);
        }
コード例 #27
0
ファイル: ZFrame.cs プロジェクト: zhangwenquan/clrzmq4
        public void MoveZeroTo(ZFrame other)
        {
            // zmq.msg_copy(dest, src)
            ZError error;

            while (-1 == zmq.msg_move(other.framePtr, framePtr))
            {
                error = ZError.GetLastErr();

                if (error == ZError.EINTR)
                {
                    error = default(ZError);
                    continue;
                }
                if (error == ZError.EFAULT)
                {
                    // Invalid message.
                }
                throw new ZException(error, "zmq_msg_move");
            }

            // When move, msg_close this _framePtr
            Close();
        }
コード例 #28
0
ファイル: ZFrame.cs プロジェクト: shenxuejin/clrzmq4
		public void MoveZeroTo(ZFrame other)
		{
			// zmq.msg_copy(dest, src)
			ZError error;
			while (-1 == zmq.msg_move(other._framePtr, _framePtr))
			{
				error = ZError.GetLastErr();

				if (error == ZError.EINTR)
				{
					error = default(ZError);
					continue;
				}
				if (error == ZError.EFAULT)
				{
					// Invalid message. 
				}
				throw new ZException(error, "zmq_msg_move");
			}

			// When move, msg_close this _framePtr
			Close();
		}
コード例 #29
0
ファイル: ZFrame.cs プロジェクト: shenxuejin/clrzmq4
		public static ZFrame CopyFrom(ZFrame frame)
		{
			return frame.Duplicate();
		}
コード例 #30
0
ファイル: mdbroker.cs プロジェクト: ray-zong/zguide
 /// <summary>
 /// 
 /// </summary>
 /// <param name="idString"></param>
 /// <param name="broker"></param>
 /// <param name="identity">will be dublicated inside the constructor</param>
 public Worker(string idString, Broker broker, ZFrame identity)
 {
     Broker = broker;
     IdString = idString;
     Identity = identity.Duplicate();
 }
コード例 #31
0
ファイル: mdbroker.cs プロジェクト: ray-zong/zguide
            //  .split worker methods
            //  Here is the implementation of the methods that work on a worker:

            //  Lazy constructor that locates a worker by identity, or creates a new
            //  worker if there is no worker already with that identity.
            public Worker RequireWorker(ZFrame identity)
            {
                if (identity == null)
                    throw new InvalidOperationException();

                string idString;
                using (var tstfrm = identity.Duplicate())
                {
                    idString = tstfrm.Read().ToHexString();
                }
                
                Worker worker = Workers.ContainsKey(idString)
                    ? Workers[idString]
                    : null;

                if (worker == null)
                {
                    worker = new Worker(idString, this, identity);
                    Workers[idString] = worker;
                    if(Verbose)
                        "I: registering new worker: '{0}'".DumpString(idString);
                }
                
                return worker;
            }
コード例 #32
0
ファイル: mdbroker.cs プロジェクト: ray-zong/zguide
            //  .split service methods
            //  Here is the implementation of the methods that work on a service:

            //  Lazy constructor that locates a service by name or creates a new
            //  service if there is no service already with that name.
            public Service RequireService(ZFrame serviceFrame)
            {
                if(serviceFrame == null)
                    throw new InvalidOperationException();

                string name = serviceFrame.ToString();

                Service service;
                if (Services.ContainsKey(name))
                {
                    service = Services[name];
                }
                else
                {
                    service = new Service(this, name);
                    Services[name] = service;

                    //zhash_freefn(self->workers, id_string, s_worker_destroy);
                    if (Verbose)
                        "I: added service: '{0}'".DumpString(name);
                }

                return service;
            }
コード例 #33
0
ファイル: ZSocket.cs プロジェクト: zmapi/ctst4-acmd
 public virtual bool SendFrame(ZFrame msg, out ZError error)
 {
     return(SendFrame(msg, ZSocketFlags.None, out error));
 }
コード例 #34
0
ファイル: mdwrkapi.cs プロジェクト: ChenXuJasper/zguide
			//  .split recv method
			//  This is the {{recv}} method; it's a little misnamed because it first sends
			//  any reply and then waits for a new request. If you have a better name
			//  for this, let me know.

			//  Send reply, if any, to broker and wait for next request.
			public ZMessage Recv(ZMessage reply, CancellationTokenSource cancellor)
			{
				if (reply == null
					&& _expectReply)
					throw new InvalidOperationException();

				if (reply != null)
				{
					if(_replyTo == null)
						throw new InvalidOperationException();
					reply.Wrap(_replyTo);
					SendToBroker(MdpCommon.MdpwCmd.REPLY.ToHexString(), string.Empty, reply);
				}
				_expectReply = true;

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

					var p = ZPollItem.CreateReceiver();
					ZMessage msg;
					ZError error;
					if (Worker.PollIn(p, out msg, out error, Heartbeat))
					{
						using (msg)
						{
							// If we got a reply
							if (Verbose)
								msg.DumpZmsg("I: received message from broker:");

							Liveness = MdpCommon.HEARTBEAT_LIVENESS;

							// Don't try to handle errors, just assert noisily
							if(msg.Count < 3)
								throw new InvalidOperationException();

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

							using (ZFrame header = msg.Pop())
							{
								if (!header.ToString().Equals(MdpCommon.MDPW_WORKER))
									throw new InvalidOperationException();
							}
							//header.ReadString().Equals(MDPW_WORKER);
							using (ZFrame command = msg.Pop())
							{
								if (command.StrHexEq(MdpCommon.MdpwCmd.REQUEST))
								{
									//  We should pop and save as many addresses as there are
									//  up to a null part, but for now, just save one...
									_replyTo = msg.Unwrap();

									//  .split process message
									//  Here is where we actually have a message to process; we
									//  return it to the caller application:
									return msg.Duplicate();
								}
								else if (command.StrHexEq(MdpCommon.MdpwCmd.HEARTBEAT))
								{
									// Do nothing for heartbeats
								}
								else if (command.StrHexEq(MdpCommon.MdpwCmd.DISCONNECT))
								{
									ConnectToBroker();
								}
								else
									"E: invalid input message: '{0}'".DumpString(command.ToString());
							}
						}
					}
					else if (Equals(error, ZError.ETERM))
					{
						cancellor.Cancel();
						break; // Interrupted
					}
					else if (Equals(error, ZError.EAGAIN) 
							 && --Liveness == 0)
					{
						if (Verbose)
							"W: disconnected from broker - retrying...".DumpString();
						Thread.Sleep(Reconnect);
						ConnectToBroker();
					}

					// Send HEARTBEAT if it's time
					if (DateTime.UtcNow > HeartbeatAt)
					{
						SendToBroker(MdpCommon.MdpwCmd.HEARTBEAT.ToHexString(), null, null);
						HeartbeatAt = DateTime.UtcNow + Heartbeat;
					}
				}
				if (cancellor.IsCancellationRequested)
					"W: interrupt received, killing worker...\n".DumpString();

				return null;
			}
コード例 #35
0
ファイル: ZSocket.cs プロジェクト: zmapi/ctst4-acmd
        }         // just Send*

        public virtual bool SendMore(ZFrame msg, out ZError error)
        {
            return(SendFrameMore(msg, out error));
        }         // just Send*
コード例 #36
0
ファイル: flclient1.cs プロジェクト: ray-zong/zguide
		static int FLClient1_MAX_RETRIES = 3;	// Before we abandon

		public static void FLClient1(string[] args)
		{
			//
			// Freelance client - Model 1
			// Uses REQ socket to query one or more services
			//
			// Author: metadings
			//

			if (args == null || args.Length < 1)
			{
				Console.WriteLine();
				Console.WriteLine("Usage: ./{0} FLClient1 [Endpoint]", AppDomain.CurrentDomain.FriendlyName);
				Console.WriteLine();
				Console.WriteLine("    Endpoint  Where FLClient1 should connect to.");
				Console.WriteLine("              Default is tcp://127.0.0.1:7780");
				Console.WriteLine();
				args = new string[] { "tcp://127.0.0.1:7780" };
			}

			// The client uses a Lazy Pirate strategy if it only has one server to talk
			// to. If it has two or more servers to talk to, it will try each server just
			// once:

			using (var context = new ZContext())
			using (var request = new ZFrame("Hello World"))
			{
				ZFrame reply = null;

				if (args.Length == 1)
				{
					// For one endpoint, we retry N times
					string endpoint = args[0];

					for (int retries = 0; retries < FLClient1_MAX_RETRIES; ++retries)
					{
						if (null != (reply = FLClient1_TryRequest(context, endpoint, request)))
						{
							break;	// Successful
						}
						Console.WriteLine("W: no response from {0}, retrying...", endpoint);
					}
				}
				else
				{
					// For multiple endpoints, try each at most once

					for (int endpoint_nbr = 0; endpoint_nbr < args.Length; ++endpoint_nbr)
					{
						string endpoint = args[endpoint_nbr];

						if (null != (reply = FLClient1_TryRequest(context, endpoint, request)))
						{
							break;	// Successful
						}
						Console.WriteLine("W: no response from {0}, retrying...", endpoint);
					}
				}

				if (reply != null)
				{
					Console.WriteLine("Service is running OK");
				}
			}
		}
コード例 #37
0
ファイル: ZSocket.cs プロジェクト: zmapi/ctst4-acmd
        }         // just Send*

        public virtual bool Send(ZFrame frame, ZSocketFlags flags, out ZError error)
        {
            return(SendFrame(frame, flags, out error));
        }         // just Send*
コード例 #38
0
ファイル: flcliapi.cs プロジェクト: ChenXuJasper/zguide
			public static void Agent(ZContext context, ZSocket backend, CancellationTokenSource cancellor, object[] args)
			{
				// Finally, here's the agent task itself, which polls its two sockets
				// and processes incoming messages:

				using (var agent = new Agent(context, backend))
				{
					var p = ZPollItem.CreateReceiver();

					while (!cancellor.IsCancellationRequested)
					{
						ZMessage msg;
						ZError error;

						// Poll the control message

						if (agent.Pipe.PollIn(p, out msg, out error, TimeSpan.FromMilliseconds(64)))
						{
							using (msg)
							{
								agent.ControlMessage(msg);
							}
						}
						else
						{
							if (error == ZError.ETERM)
								break;	// Interrupted
							if (error != ZError.EAGAIN)
								throw new ZException(error);
						}

						// Poll the router message

						if (agent.Router.PollIn(p, out msg, out error, TimeSpan.FromMilliseconds(64)))
						{
							using (msg)
							{
								agent.RouterMessage(msg);
							}
						}
						else
						{
							if (error == ZError.ETERM)
								break;	// Interrupted
							if (error != ZError.EAGAIN)
								throw new ZException(error);
						}

						if (agent.Request != null)
						{
							// If we're processing a request, dispatch to next server

							if (DateTime.UtcNow >= agent.Expires)
							{
								// Request expired, kill it
								using (var outgoing = new ZFrame("FAILED"))
								{
									agent.Pipe.Send(outgoing);
								}

								agent.Request.Dispose();
								agent.Request = null;
							}
							else
							{
								// Find server to talk to, remove any expired ones
								foreach (Server server in agent.Actives.ToList())
								{
									if (DateTime.UtcNow >= server.Expires)
									{
										agent.Actives.Remove(server);
										server.Alive = false;
									}
									else
									{
										// Copy the Request, Push the Endpoint and send on Router
										using (var request = agent.Request.Duplicate())
										{
											request.Prepend(new ZFrame(server.Endpoint));

											agent.Router.Send(request);
											break;
										}
									}
								}
							}
						}

						// Disconnect and delete any expired servers
						// Send heartbeats to idle servers if needed
						foreach (Server server in agent.Servers)
						{
							server.Ping(agent.Router);
						}
					}
				}
			}
コード例 #39
0
ファイル: ZSocket.cs プロジェクト: zmapi/ctst4-acmd
        }         // just Send*

        public virtual void Send(ZFrame frame, ZSocketFlags flags)
        {
            SendFrame(frame, flags);
        }         // just Send*
コード例 #40
0
ファイル: ppworker.cs プロジェクト: ChenXuJasper/zguide
		public static void PPWorker(string[] args)
		{
			if (args == null || args.Length == 0)
			{
				Console.WriteLine();
				Console.WriteLine("Usage: ./{0} PPWorker [Name]", AppDomain.CurrentDomain.FriendlyName);
				Console.WriteLine();
				Console.WriteLine("    Name   Your name. Default: World");
				Console.WriteLine();
				args = new string[] { "World" };
			}
			string name = args[0];

			ZError error;
			using (var context = new ZContext())
			{
				ZSocket worker = null;
				try // using (worker)
				{
					if (null == (worker = PPWorker_CreateZSocket(context, name, out error)))
					{
						if (error == ZError.ETERM)
							return;	// Interrupted
						throw new ZException(error);
					}

					// If liveness hits zero, queue is considered disconnected
					int liveness = Worker.PPP_HEARTBEAT_LIVENESS;
					int interval = Worker.PPP_INTERVAL_INIT;

					// Send out heartbeats at regular intervals
					DateTime heartbeat_at = DateTime.UtcNow + Worker.PPP_HEARTBEAT_INTERVAL;

					ZMessage incoming;
					int cycles = 0;
					var poll = ZPollItem.CreateReceiver();
					var rnd = new Random();

					while (true)
					{
						if (worker.PollIn(poll, out incoming, out error, Worker.PPP_TICK))
						{
							// Get message
							// - 3-part envelope + content -> request
							// - 1-part HEARTBEAT -> heartbeat
							using (incoming)
							{
								// To test the robustness of the queue implementation we
								// simulate various typical problems, such as the worker
								// crashing or running very slowly. We do this after a few
								// cycles so that the architecture can get up and running
								// first:
								if (incoming.Count >= 3)
								{
									Console_WriteZMessage("I: receiving reply", incoming);

									cycles++;
									if (cycles > 3 && rnd.Next(5) == 0)
									{
										Console.WriteLine("I: simulating a crash");
										return;
									}
									if (cycles > 3 && rnd.Next(3) == 0)
									{
										Console.WriteLine("I: simulating CPU overload");
										Thread.Sleep(100);
									}

									Thread.Sleep(1);	// Do some heavy work

									Console.WriteLine("I: sending reply");
									worker.Send(incoming);

									liveness = Worker.PPP_HEARTBEAT_LIVENESS;
								}
								// When we get a heartbeat message from the queue, it means the
								// queue was (recently) alive, so we must reset our liveness
								// indicator:
								else if (incoming.Count == 1)
								{
									string identity = incoming[0].ReadString();

									if (identity == Worker.PPP_HEARTBEAT)
									{
										Console.WriteLine("I: receiving heartbeat");
										liveness = Worker.PPP_HEARTBEAT_LIVENESS;
									}
									else
									{
										Console_WriteZMessage("E: invalid message", incoming);
									}
								}
								else
								{
									Console_WriteZMessage("E: invalid message", incoming);
								}
							}
							interval = Worker.PPP_INTERVAL_INIT;
						}
						else
						{
							if (error == ZError.ETERM)
								break;	// Interrupted
							if (error != ZError.EAGAIN)
								throw new ZException(error);
						}

						if (error == ZError.EAGAIN)
						{
							// If the queue hasn't sent us heartbeats in a while, destroy the
							// socket and reconnect. This is the simplest most brutal way of
							// discarding any messages we might have sent in the meantime:
							if (--liveness == 0)
							{
								Console.WriteLine("W: heartbeat failure, can't reach queue");
								Console.WriteLine("W: reconnecting in {0} ms", interval);
								Thread.Sleep(interval);

								if (interval < Worker.PPP_INTERVAL_MAX)
								{
									interval *= 2;
								}
								else {
									Console.WriteLine("E: interrupted");
									break;
								}

								worker.Dispose();
								if (null == (worker = PPWorker_CreateZSocket(context, name, out error)))
								{
									if (error == ZError.ETERM)
										break;	// Interrupted
									throw new ZException(error);
								}
								liveness = Worker.PPP_HEARTBEAT_LIVENESS;
							}
						}

						// Send heartbeat to queue if it's time
						if (DateTime.UtcNow > heartbeat_at) 
						{
							heartbeat_at = DateTime.UtcNow + Worker.PPP_HEARTBEAT_INTERVAL;

							Console.WriteLine("I:   sending heartbeat");
							using (var outgoing = new ZFrame(Worker.PPP_HEARTBEAT))
							{
								worker.Send(outgoing);
							}
						}
					}
				}
				finally
				{
					if (worker != null)
					{
						worker.Dispose();
						worker = null;
					}
				}
			}
		}
コード例 #41
0
ファイル: ZSocket.cs プロジェクト: zmapi/ctst4-acmd
 public virtual void SendFrameMore(ZFrame frame, ZSocketFlags flags)
 {
     SendFrame(frame, flags | ZSocketFlags.More);
 }
コード例 #42
0
ファイル: ZSocket.cs プロジェクト: zmapi/ctst4-acmd
        }         // just Send*

        public virtual void SendMore(ZFrame frame)
        {
            SendFrameMore(frame);
        }         // just Send*
コード例 #43
0
ファイル: mdbroker.cs プロジェクト: ray-zong/zguide
            //  .split broker client_msg method
            //  Process a request coming from a client. We implement MMI requests
            //  directly here (at present, we implement only the mmi.service request):
            public void ClientMsg(ZFrame sender, ZMessage msg)
            {
                // service & body
                if(msg.Count < 2)
                    throw new InvalidOperationException();

                using (ZFrame serviceFrame = msg.Pop())
                {
                    Service service = RequireService(serviceFrame);

                    // Set reply return identity to client sender
                    msg.Wrap(sender.Duplicate());

                    //if we got a MMI Service request, process that internally
                    if (serviceFrame.Length >= 4
                        && serviceFrame.ToString().StartsWith("mmi."))
                    {
                        string returnCode;
                        if (serviceFrame.ToString().Equals("mmi.service"))
                        {
                            string name = msg.Last().ToString();
                            returnCode = Services.ContainsKey(name) 
                                         && Services[name].Workers > 0
                                            ? "200"
                                            : "404";
                        }
                        else
                            returnCode = "501";

                        var client = msg.Unwrap();
                        
                        msg.Clear();
                        msg.Add(new ZFrame(returnCode));
                        msg.Prepend(serviceFrame);
                        msg.Prepend(new ZFrame(MdpCommon.MDPC_CLIENT));

                        msg.Wrap(client);
                        Socket.Send(msg);
                    }
                    else
                    {
                        // Else dispatch the message to the requested Service
                        service.Dispatch(msg);
                    }
                }
            }
コード例 #44
0
ファイル: ZFrame.cs プロジェクト: ym1100/MicroZero
 public static ZFrame CopyFrom(ZFrame frame)
 {
     return(frame.Duplicate());
 }
コード例 #45
0
ファイル: ZSocket.cs プロジェクト: zmapi/ctst4-acmd
 public virtual void SendFrame(ZFrame frame)
 {
     SendFrame(frame, ZSocketFlags.None);
 }
コード例 #46
0
            /// <summary>
            /// Receive a valid ZAP request from the handler socket
            /// </summary>
            /// <param name="handler"></param>
            /// <param name="request"></param>
            /// <param name="verbose"></param>
            public ZAP(ZSocket handler, ZMessage request, bool verbose)
            {
                //  Store handler socket so we can send a reply easily
                this.handler = handler;
                Verbose      = verbose;

                if (request.Count == 0)
                {
                    return;
                }

                //  Get all standard frames off the handler socket
                Version   = request.Pop().ReadLine();
                Sequence  = request.Pop().ReadLine();
                Domain    = request.Pop().ReadLine();
                Address   = request.Pop().ReadLine();
                Identity  = request.Pop().ReadLine();
                Mechanism = request.Pop().ReadLine();

                Mechanism = string.IsNullOrEmpty(Mechanism) ? "" : Mechanism;
                Version   = string.IsNullOrEmpty(Version) ? "" : Version;
                Sequence  = string.IsNullOrEmpty(Sequence) ? "" : Sequence;
                Domain    = string.IsNullOrEmpty(Domain) ? "" : Domain;
                Address   = string.IsNullOrEmpty(Address) ? "" : Address;
                Identity  = string.IsNullOrEmpty(Identity) ? "" : Identity;


                //  If the version is wrong, we're linked with a bogus libzmq, so die
                if (Version != "1.0")
                {
                    return;
                }

                //  Get mechanism-specific frames
                if (Mechanism == "PLAIN")
                {
                    Username = request.Pop().ReadLine();
                    Password = request.Pop().ReadLine();
                    Username = string.IsNullOrEmpty(Username) ? "" : Username;
                    Password = string.IsNullOrEmpty(Password) ? "" : Password;
                }
                else
                if (Mechanism == "CURVE")
                {
                    ZFrame frame = request.Pop();

                    if (frame.Length != 32)
                    {
                        return;
                    }
                    ZCert cert = new ZCert(frame.Read(), new byte[32]);
                    ClientTxt = cert.PublicTxt;
                }
                else
                if (Mechanism == "GSSAPI")
                {
                    Principal = request.Pop().ReadLine();
                }

                if (Verbose)
                {
                    ZAuth.Info(string.Format("zauth: ZAP request mechanism={0} ipaddress={1}", Mechanism, Address));
                }
            }
コード例 #47
0
ファイル: peering2.cs プロジェクト: ray-zong/zguide
		static void Peering2_WorkerTask(ZContext context, int i, string name) 
		{
			// The worker task plugs into the load-balancer using a REQ socket

			using (var worker = new ZSocket(context, ZSocketType.REQ))
			{
				// Set printable identity
				worker.IdentityString = name;

				// Connect
				worker.Connect("tcp://127.0.0.1:" + Peering2_GetPort(name) + 2);

				// Tell broker we're ready for work
				worker.Send(new ZFrame("READY"));

				// Process messages as they arrive
				ZError error;
				while (true)
				{
					// Receive
					ZFrame incoming = worker.ReceiveFrame(out error);

					if (incoming == null)
					{
						if (error == ZError.ETERM)
							return;	// Interrupted

						throw new ZException(error);
					}
					using (incoming)
					{
						Console.WriteLine("Worker {0}: {1}", name, incoming.ReadString());

						// Do some heavy work
						Thread.Sleep(1);

						// Send
						using (var outgoing = new ZFrame("OK"))
						{
							worker.Send(outgoing);
						}
					}
				}
			}
		}
コード例 #48
0
        private int HandlePipe(ZMessage request)
        {
            if (request.Count == 0)
            {
                return(-1);                  //  Interrupted
            }
            ZFrame commandFrame = request.Pop();
            string command      = commandFrame.ReadLine();

            if (verbose)
            {
                Info("zauth: API command=" + command);
            }

            if (command == "ALLOW")
            {
                while (request.Count > 0)
                {
                    ZFrame frame   = request.Pop();
                    string address = frame.ReadLine();
                    if (verbose)
                    {
                        Info("zauth: - whitelisting ipaddress=" + address);
                    }

                    if (!whitelist.Contains(address))
                    {
                        whitelist.Add(address);
                    }
                }
                //
                sockets[PIPE].SendFrame(new ZFrame(0));
            }
            else
            if (command == "DENY")
            {
                while (request.Count > 0)
                {
                    ZFrame frame   = request.Pop();
                    string address = frame.ReadLine();
                    if (verbose)
                    {
                        Info("zauth: - blacklisting ipaddress=" + address);
                    }

                    if (!blacklist.Contains(address))
                    {
                        blacklist.Add(address);
                    }
                    if (whitelist.Contains(address))
                    {
                        whitelist.Remove(address);
                    }
                }
                sockets[PIPE].SendFrame(new ZFrame(0));
            }
            else
            if (command == "PLAIN")
            {
                //  Get password file and load into zhash table
                //  If the file doesn't exist we'll get an empty table
                ZFrame frame    = request.Pop();
                string filename = frame.ReadLine();
                if (Load(out passwords, filename) != 0 && verbose)
                {
                    Info("zauth: could not load file=" + filename);
                }
                sockets[PIPE].SendFrame(new ZFrame(0));
            }
            else
            if (command == "CURVE")
            {
                //  If location is CURVE_ALLOW_ANY, allow all clients. Otherwise
                //  treat location as a directory that holds the certificates.
                ZFrame frame    = request.Pop();
                string location = frame.ReadLine();
                if (location == CURVE_ALLOW_ANY)
                {
                    allowAny = true;
                }
                else
                {
                    certStore = new ZCertStore(location);
                    allowAny  = false;
                }
                sockets[PIPE].SendFrame(new ZFrame(0));
            }
            else
            if (command == "GSSAPI")
            {
                //  GSSAPI authentication is not yet implemented here
                sockets[PIPE].SendFrame(new ZFrame(0));
            }
            else
            if (command == "VERBOSE")
            {
                verbose = true;
                sockets[PIPE].SendFrame(new ZFrame(0));
            }
            else
            if (command == "$TERM")
            {
                Terminated = true;
            }
            else
            {
                Error("zauth: - invalid command: " + command);
            }
            return(0);
        }
コード例 #49
0
ファイル: mdbroker.cs プロジェクト: ray-zong/zguide
            //  .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");
                    }
                }
            }
コード例 #50
0
ファイル: ZSocket.cs プロジェクト: zmapi/ctst4-acmd
 public virtual bool SendFrameMore(ZFrame msg, ZSocketFlags flags, out ZError error)
 {
     return(SendFrame(msg, flags | ZSocketFlags.More, out error));
 }
コード例 #51
0
ファイル: spworker.cs プロジェクト: ChenXuJasper/zguide
        public static void SPWorker(string[] args)
        {
            //
            // Simple Pirate worker
            // Connects REQ socket to tcp://127.0.0.1:5556
            // Implements worker part of load-balancing
            //
            // Author: metadings
            //

            var rnd = new Random();
            if (args == null || args.Length < 1)
            {
                args = new string[] { "World" + rnd.Next() };
            }
            string name = args[0];

            using (var context = new ZContext())
            using (var worker = new ZSocket(context, ZSocketType.REQ))
            {
                worker.Identity = Encoding.UTF8.GetBytes(name);
                worker.Connect("tcp://127.0.0.1:5556");

                Console.WriteLine("I: ({0}) worker ready", name);

                using (var outgoing = new ZFrame("READY"))
                {
                    worker.Send(outgoing);
                }

                int cycles = 0;
                ZError error;
                ZMessage incoming;

                while (true)
                {
                    if (null == (incoming = worker.ReceiveMessage(out error)))
                    {
                        if (error == ZError.ETERM)
                            return;

                        throw new ZException(error);
                    }
                    using (incoming)
                    {
                        // Simulate various problems, after a few cycles
                        cycles++;

                        if (cycles > 3 && rnd.Next(5) == 0)
                        {
                            Console.WriteLine("I: ({0}) simulating a crash", name);
                            return;
                        }
                        else if (cycles > 3 && rnd.Next(5) == 0)
                        {
                            Console.WriteLine("I: ({0}) simulating CPU overload", name);
                            Thread.Sleep(500);
                        }

                        Console.WriteLine("I: ({0}) normal reply", name);

                        Thread.Sleep(1); // Do some heavy work

                        // Send message back
                        worker.Send(incoming);
                    }
                }

            }
        }