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); }
public static void PPQueue(IDictionary <string, string> dict, string[] args) { using (var context = ZContext.Create()) using (var backend = ZSocket.Create(context, ZSocketType.ROUTER)) using (var frontend = ZSocket.Create(context, ZSocketType.ROUTER)) { backend.Bind("tcp://*:5556"); frontend.Bind("tcp://*:5555"); // List of available workers var workers = new List <Worker>(); // Send out heartbeats at regular intervals DateTime heartbeat_at = DateTime.UtcNow + Worker.PPP_HEARTBEAT_INTERVAL; // Create a Receiver ZPollItem (ZMQ_POLLIN) var poll = ZPollItem.CreateReceiver(); ZError error; ZMessage incoming; while (true) { // Handle worker activity on backend if (backend.PollIn(poll, out incoming, out error, Worker.PPP_TICK)) { using (incoming) { // Any sign of life from worker means it's ready ZFrame identity = incoming.Unwrap(); var worker = new Worker(identity); workers.Ready(worker); // Validate control message, or return reply to client if (incoming.Count == 1) { string message = incoming[0].ReadString(); if (message == Worker.PPP_READY) { Console.WriteLine("I: worker ready ({0})", worker.IdentityString); } else if (message == Worker.PPP_HEARTBEAT) { Console.WriteLine("I: receiving heartbeat ({0})", worker.IdentityString); } else { Console_WriteZMessage(incoming, "E: invalid message from worker"); } } else { Console_WriteZMessage(incoming, "I: [backend sending to frontend] ({0})", worker.IdentityString); frontend.Send(incoming); } } } else { if (error == ZError.ETERM) { break; // Interrupted } if (error != ZError.EAGAIN) { throw new ZException(error); } } // Handle client activity on frontend if (workers.Count > 0) { // Poll frontend only if we have available workers if (frontend.PollIn(poll, out incoming, out error, Worker.PPP_TICK)) { // Now get next client request, route to next worker using (incoming) { ZFrame workerIdentity = workers.Next(); incoming.Prepend(workerIdentity); Console_WriteZMessage(incoming, "I: [frontend sending to backend] ({0})", workerIdentity.ReadString()); // Console.WriteLine("I: route to next worker [frontend send to backend] ({0})", workerIdentity.ReadString()); backend.Send(incoming); } } else { if (error == ZError.ETERM) { break; // Interrupted } if (error != ZError.EAGAIN) { throw new ZException(error); } } } // We handle heartbeating after any socket activity. First, we send // heartbeats to any idle workers if it's time. Then, we purge any // dead workers: if (DateTime.UtcNow > heartbeat_at) { heartbeat_at = DateTime.UtcNow + Worker.PPP_HEARTBEAT_INTERVAL; foreach (Worker worker in workers) { using (var outgoing = new ZMessage()) { outgoing.Add(ZFrame.CopyFrom(worker.Identity)); outgoing.Add(new ZFrame(Worker.PPP_HEARTBEAT)); Console.WriteLine("I: sending heartbeat ({0})", worker.IdentityString); backend.Send(outgoing); } } } workers.Purge(); } // When we're done, clean up properly foreach (Worker worker in workers) { worker.Dispose(); } } }