Esempio n. 1
0
        public static void TaskWork2(IDictionary <string, string> dict, string[] args)
        {
            //
            // Task worker - design 2
            // Adds pub-sub flow to receive and respond to kill signal
            //
            // Author: metadings
            //

            // Socket to receive messages on,
            // Socket to send messages to and
            // Socket for control input
            using (var context = ZContext.Create())
                using (var receiver = ZSocket.Create(context, ZSocketType.PULL))
                    using (var sender = ZSocket.Create(context, ZSocketType.PUSH))
                        using (var controller = ZSocket.Create(context, ZSocketType.SUB))
                        {
                            receiver.Connect("tcp://127.0.0.1:5557");
                            sender.Connect("tcp://127.0.0.1:5558");

                            controller.Connect("tcp://127.0.0.1:5559");
                            controller.SubscribeAll();

                            var poll = ZPollItem.CreateReceiver();

                            ZError   error;
                            ZMessage message;
                            while (true)
                            {
                                // Process messages from either socket
                                if (receiver.PollIn(poll, out message, out error, TimeSpan.FromMilliseconds(64)))
                                {
                                    int workload = message[0].ReadInt32();
                                    Console.WriteLine("{0}.", workload); // Show progress

                                    Thread.Sleep(workload);              // Do the work

                                    sender.Send(new byte[0], 0, 0);      // Send results to sink
                                }

                                // Any waiting controller command acts as 'KILL'
                                if (controller.PollIn(poll, out message, out error, TimeSpan.FromMilliseconds(64)))
                                {
                                    break;              // Exit loop
                                }
                            }
                        }
        }
Esempio n. 2
0
        public void PollMany_Single_Timeout()
        {
            using (var context = new ZContext())
            {
                using (var socket = new ZSocket(context, ZSocketType.PAIR))
                {
                    var sockets   = new[] { socket };
                    var pollItems = new[] { ZPollItem.CreateReceiver() };

                    ZMessage[] messages = null;
                    ZError     error;
                    Assert.IsFalse(sockets.Poll(pollItems, ZPoll.In, ref messages, out error, TimeSpan.Zero));

                    CollectionAssert.AreEqual(new ZMessage[] { null }, messages);
                    Assert.AreEqual(ZError.EAGAIN, error);
                }
            }
        }
Esempio n. 3
0
        /// <summary>
        /// 代理2
        /// </summary>
        /// <param name="context"></param>
        public static void RRBroker(ZContext context)
        {
            using (var ctx = new ZContext())
                using (var frontend = new ZSocket(ctx, ZSocketType.ROUTER))
                    using (var backend = new ZSocket(ctx, ZSocketType.DEALER))
                    {
                        frontend.Bind("tcp://*:5570");
                        backend.Bind("inproc://backend");
                        Thread.Sleep(2000);
                        //backend.SendFrame(new ZFrame("hahah"));

                        var poll = ZPollItem.CreateReceiver();
                        while (true)
                        {
                            if (frontend.PollIn(poll, out var message, out var error, TimeSpan.FromMilliseconds(64)))
                            {
                                backend.Send(message);
                            }
Esempio n. 4
0
        // private static readonly int sizeof_MonitorEventData = Marshal.SizeOf(typeof(ZMonitorEventData));

        /// <summary>
        /// Begins monitoring for state changes, raising the appropriate events as they arrive.
        /// </summary>
        /// <remarks>NOTE: This is a blocking method and should be run from another thread.</remarks>
        protected override void Run()
        {
            _socket.Connect(_endpoint);

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

            while (!Cancellor.IsCancellationRequested)
            {
                if (!_socket.PollIn(poller, out incoming, out error, PollingInterval))
                {
                    if (error == ZError.EAGAIN)
                    {
                        Thread.Sleep(1);
                        continue;
                    }

                    throw new ZException(error);
                }

                var eventValue = new ZMonitorEventData();

                using (incoming) {
                    if (incoming.Count > 0)
                    {
                        eventValue.Event      = (ZMonitorEvents)incoming[0].ReadInt16();
                        eventValue.EventValue = incoming[0].ReadInt32();
                    }

                    if (incoming.Count > 1)
                    {
                        eventValue.Address = incoming[1].ReadString();
                    }
                }

                OnMonitor(eventValue);
            }

            if (!_socket.Disconnect(_endpoint, out error))
            {
            }                                                              // ignore errors
        }
Esempio n. 5
0
        public void PollOutSingle_Ready()
        {
            using (var context = new ZContext())
            {
                using (var socket1 = new ZSocket(context, ZSocketType.PAIR))
                {
                    socket1.Bind(DefaultEndpoint);
                    using (var socket2 = new ZSocket(context, ZSocketType.PAIR))
                    {
                        socket2.Connect(DefaultEndpoint);

                        ZError error;
                        Assert.IsTrue(socket1.PollOut(ZPollItem.CreateSender(), new ZMessage(new[] { new ZFrame(32) }), out error, TimeSpan.Zero));
                        Assert.IsNull(error);

                        var message = socket2.ReceiveMessage();
                        Assert.AreEqual(new ZMessage(new[] { new ZFrame(32) }), message);
                    }
                }
            }
        }
Esempio n. 6
0
        public void PollInSingle_CancelByContextClose()
        {
            Task   task;
            ZError error = null;

            using (var context = new ZContext())
            {
                var socket = new ZSocket(context, ZSocketType.PAIR);
                task = Task.Run(() =>
                {
                    using (socket)
                    {
                        ZMessage message;

                        socket.PollIn(ZPollItem.CreateReceiver(), out message, out error);
                    }
                });
            }
            Assert.IsTrue(task.Wait(1000));
            Assert.AreEqual(ZError.ETERM, error);
        }
Esempio n. 7
0
        public JupyterMessage Execute(string code)
        {
            FlushMessages();
            CurrentState = KernelState.busy;
            SendShell(
                JupyterMessage.Header.MsgType.execute_request,
                new JupyterMessage.ExecuteRequestContent
            {
                code             = code,
                silent           = false,
                store_history    = true,
                user_expressions = null,
                allow_stdin      = true,
                stop_on_error    = false
            },
                null);

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

            while (CurrentState != KernelState.idle)
            {
                if (StdInSocket.PollIn(poll, out incoming, out error, TimeSpan.FromMilliseconds(100)))
                {
                    ProcessMessage(incoming, error);
                }

                if (IoPubSocket.PollIn(poll, out incoming, out error, TimeSpan.FromMilliseconds(100)))
                {
                    ProcessMessage(incoming, error);
                }
            }

            var replyMessage = ShellSocket.ReceiveMessage();

            return(ParseMessage(replyMessage));
        }
Esempio n. 8
0
        /// <summary>
        /// 接收完关闭模式
        /// </summary>
        /// <param name="args"></param>
        public static void TaskWork2(string[] args)
        {
            using (var context = new ZContext())
                using (var receiver = new ZSocket(context, ZSocketType.PULL))
                    using (var sender = new ZSocket(context, ZSocketType.PUSH))
                        using (var controller = new ZSocket(context, ZSocketType.SUB))
                        {
                            receiver.Connect("tcp://127.0.0.1:5557");
                            sender.Connect("tcp://127.0.0.1:5558");

                            controller.Connect("tcp://127.0.0.1:5559");
                            controller.SubscribeAll();

                            var poll = ZPollItem.CreateReceiver();

                            ZError   error;
                            ZMessage message;
                            while (true)
                            {
                                // Process messages from either socket
                                if (receiver.PollIn(poll, out message, out error, TimeSpan.FromMilliseconds(64)))
                                {
                                    int workload = message[0].ReadInt32();
                                    Console.WriteLine("{0}.", workload); // Show progress

                                    Thread.Sleep(workload);              // Do the work

                                    sender.Send(new byte[0], 0, 0);      // Send results to sink
                                }

                                // Any waiting controller command acts as 'KILL'
                                if (controller.PollIn(poll, out message, out error, TimeSpan.FromMilliseconds(64)))
                                {
                                    break; // Exit loop
                                }
                            }
                        }
        }
Esempio n. 9
0
        public void PollInMany_CancelByContextClose()
        {
            Task   task;
            ZError error = null;

            using (var context = new ZContext())
            {
                var socket = new ZSocket(context, ZSocketType.PAIR);
                task = Task.Run(() =>
                {
                    using (socket)
                    {
                        var sockets   = new[] { socket };
                        var pollItems = new[] { ZPollItem.CreateReceiver() };

                        ZMessage[] messages;
                        sockets.PollIn(pollItems, out messages, out error, TimeSpan.Zero);
                    }
                });
            }
            Assert.IsTrue(task.Wait(1000));
            Assert.AreEqual(ZError.ETERM, error);
        }
Esempio n. 10
0
        /// <summary>
        /// We need two queues, one for requests from local clients and one for requests from cloud
        /// clients.One option would be to pull messages off the local and cloud frontends and
        /// pump these onto their respective queues.But this is kind of pointless, because ØMQ
        /// sockets are queues already. So let’s use the ØMQ socket buffers as queues.
        ///
        /// We use broker identities to route messages between brokers.
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            var options = new Options();
            var parser  = new CommandLineParser(new CommandLineParserSettings(Console.Error));

            if (!parser.ParseArguments(args, options))
            {
                Environment.Exit(1);
            }

            using (var context = new ZContext())
                using (ZSocket cloudFrontend = new ZSocket(context, ZSocketType.ROUTER),
                       cloudBackend = new ZSocket(context, ZSocketType.ROUTER))
                    using (ZSocket localFrontend = new ZSocket(context, ZSocketType.ROUTER),
                           localBackend = new ZSocket(context, ZSocketType.ROUTER))
                        using (ZSocket stateFrontend = new ZSocket(context, ZSocketType.SUB),
                               stateBackend = new ZSocket(context, ZSocketType.PUB))
                            using (ZSocket monitorSocket = new ZSocket(context, ZSocketType.PULL))
                            {
                                var self = options.LocalFrontEndPoint;
                                // Prepare local frontend and backend
                                Console.WriteLine("localFrontend binding {0}", options.LocalFrontEndPoint);
                                localFrontend.Bind(options.LocalFrontEndPoint);

                                Console.WriteLine("localBackend binding {0}", options.LocalBackendPoint);
                                localBackend.Bind(options.LocalBackendPoint);

                                // Bind cloud frontend to endpoint. used to communicate with other broker in cluster
                                cloudFrontend.IdentityString = self;
                                Console.WriteLine("cloudFrontend binding {0}", options.CloudFrontendPoint);
                                cloudFrontend.Bind(options.CloudFrontendPoint);

                                // Connect cloud backend to all peers
                                cloudBackend.IdentityString = self;
                                foreach (var cloudBackendPoint in options.CloudBackendPoints)
                                {
                                    Console.WriteLine("I: connecting to cloud frontend at {0}", cloudBackendPoint);
                                    cloudBackend.Connect(cloudBackendPoint);
                                }

                                //  Bind state backend to endpoint
                                Console.WriteLine("stateBackend binding {0}", options.StateBackendPoint);
                                stateBackend.Bind(options.StateBackendPoint);

                                //  Connect state frontend to all peers
                                foreach (var stateFrontendPoint in options.StateFrontendPoints)
                                {
                                    Console.WriteLine("I: connecting to state backend at {0}", stateFrontendPoint);
                                    stateFrontend.Connect(stateFrontendPoint);
                                }

                                //  Prepare monitor socket
                                Console.WriteLine("monitorSocket binding {0}", options.MonitorPoint);
                                monitorSocket.Bind(options.MonitorPoint);

                                // Get user to tell us when we can start...
                                Console.WriteLine("Press ENTER when all brokers are started...");
                                Console.ReadLine();

                                //  Queue of available workers
                                int local_worker_capacity = 0;
                                int cloud_worker_capacity = 0;

                                var localworkerList = new List <string>();
                                //  .split main loop
                                //  The main loop has two parts. First, we poll workers and our two service
                                //  sockets (statefe and monitor), in any case. If we have no ready workers,
                                //  then there's no point in looking at incoming requests. These can remain
                                //  on their internal 0MQ queues:

                                ZError   error;
                                ZMessage incoming;
                                TimeSpan?waitTimeSpan;

                                var poll = ZPollItem.CreateReceiver();

                                while (true)
                                {
                                    //  Track if capacity changes during this iteration
                                    int previous = local_worker_capacity;

                                    // If we have no workers, wait indefinitely
                                    waitTimeSpan = localworkerList.Count > 0 ? (TimeSpan?)TimeSpan.FromMilliseconds(1000) : null;
                                    Console.WriteLine("workers count:{0}, waitTime:{1}", localworkerList.Count, waitTimeSpan);

                                    ZMessage msgFromWorker, msgFromCloudBacked;

                                    // Poll localBackend
                                    if (localBackend.PollIn(poll, out msgFromWorker, out error, waitTimeSpan))
                                    {
                                        msgFromWorker.DumpZmsg("--------------------------");
                                        // Handle reply from local worker
                                        string identity = msgFromWorker[0].ReadString();
                                        localworkerList.Add(identity);
                                        // If it's READY, don't route the message any further
                                        string hello = msgFromWorker[2].ReadString();
                                        if (hello == "READY")
                                        {
                                            using (msgFromWorker)
                                            {
                                                local_worker_capacity++;
                                                Console.WriteLine("Local worker is READY, don't route the ready message");
                                            }
                                            msgFromWorker = null;
                                        }
                                    }
                                    else if (error == ZError.EAGAIN && cloudBackend.PollIn(poll, out msgFromCloudBacked, out error, waitTimeSpan))
                                    {
                                        //Handle reply from peer broker

                                        // We don't use peer broker identity for anything
                                        using (msgFromCloudBacked)
                                        {
                                            string identity = msgFromCloudBacked[0].ReadString();

                                            // string ok = incoming[2].ReadString();
                                        }
                                        msgFromCloudBacked = null;
                                    }
                                    else
                                    {
                                        if (error == ZError.ETERM)
                                        {
                                            return; // Interrupted
                                        }
                                        if (error != ZError.EAGAIN)
                                        {
                                            throw new ZException(error);
                                        }
                                    }

                                    //  Route worker reply to cloud if it's addressed to a broker
                                    if (msgFromWorker != null)
                                    {
                                        Console.WriteLine("Route reply to cloud if it's addressed to a broker");
                                        // Route reply to cloud if it's addressed to a broker
                                        string identity = msgFromWorker[0].ReadString();
                                        Console.WriteLine("identity:{0}", identity);

                                        foreach (var cloudBackendPoint in options.CloudBackendPoints)
                                        {
                                            if (identity == cloudBackendPoint)
                                            {
                                                using (msgFromWorker)
                                                    cloudFrontend.Send(msgFromWorker);

                                                msgFromWorker = null;
                                                break;
                                            }
                                        }
                                    }

                                    //  Route reply to client if we still need to
                                    if (msgFromWorker != null)
                                    {
                                        Console.WriteLine("Send the worker msg to client");
                                        localFrontend.Send(msgFromWorker);
                                    }

                                    //  .split handle state messages
                                    //  If we have input messages on our statefe or monitor sockets, we
                                    //  can process these immediately:
                                    //using (var stateMsg = stateFrontend.ReceiveMessage())
                                    //{
                                    //    var peer = stateMsg[0].ReadString(Encoding.UTF8);
                                    //    var status = stateMsg[1].ReadInt32();
                                    //    cloud_worker_capacity = status;
                                    //}

                                    //using (var monitorMsg = monitorSocket.ReceiveMessage())
                                    //{
                                    //    Console.WriteLine(monitorMsg[0].ReadString(Encoding.UTF8));
                                    //}

                                    //  .split route client requests
                                    //  Now route as many clients requests as we can handle. If we have
                                    //  local capacity, we poll both localfe and cloudfe. If we have cloud
                                    //  capacity only, we poll just localfe. We route any request locally
                                    //  if we can, else we route to the cloud.

                                    ZMessage localFrontMsg = null;
                                    ZMessage cloudFrontMsg = null;
                                    while (local_worker_capacity + cloud_worker_capacity > 0)
                                    {
                                        if (localFrontend.PollIn(poll, out localFrontMsg, out error, new TimeSpan(10 * 1000)))
                                        {
                                            if (local_worker_capacity > 0)
                                            {
                                                //zframe_t* frame = (zframe_t*)zlist_pop(workers);
                                                //zmsg_wrap(msg, frame);
                                                //zmsg_send(&msg, localbe);

                                                var worker = localworkerList[0];
                                                localworkerList.RemoveAt(0);

                                                //send to client msg to worker, there is no identify
                                                localBackend.Send(new ZFrame(worker));

                                                local_worker_capacity--;
                                            }
                                        }

                                        if (local_worker_capacity <= 0)
                                        {
                                            if (cloudFrontend.PollIn(poll, out cloudFrontMsg, out error, new TimeSpan(10 * 1000)))
                                            {
                                                //  Route to random broker peer
                                                var tempRamdom = new Random(options.CloudBackendPoints.Count - 1);
                                                var cbIndex    = tempRamdom.Next();
                                                cloudBackend.Send(new ZFrame(options.CloudBackendPoints[cbIndex]));
                                                //int peer = randof(argc - 2) + 2;
                                                //zmsg_pushmem(msg, argv[peer], strlen(argv[peer]));
                                                //zmsg_send(&msg, cloudbe);
                                            }
                                        }

                                        if (localFrontMsg == null && cloudFrontMsg == null)
                                        {
                                            //  No work, go back to primary
                                            break;
                                        }
                                    }

                                    //  .split broadcast capacity
                                    //  We broadcast capacity messages to other peers; to reduce chatter,
                                    //  we do this only if our capacity changed.

                                    if (local_worker_capacity != previous)
                                    {
                                        //  We stick our own identity onto the envelope
                                        var statemsg = new ZMessage();

                                        statemsg.Add(new ZFrame(self));
                                        statemsg.Add(new ZFrame(local_worker_capacity));

                                        //  Broadcast new capacity
                                        stateBackend.Send(statemsg);
                                    }
                                }
                                //end of while true
                            }
        }
Esempio n. 11
0
        // The main task begins by setting-up its frontend and backend sockets
        // and then starting its client and worker tasks:
        public static void Peering2(string[] args)
        {
            // First argument is this broker's name
            // Other arguments are our peers' names
            //
            if (args == null || args.Length < 3)
            {
                if (args != null && args.Length == 1)
                {
                    args = new string[] { args[0], "Me", "You" };
                }
                else
                {
                    Console.WriteLine("Usage: {0} Peering2 Hello Me You", AppDomain.CurrentDomain.FriendlyName);
                    Console.WriteLine("       {0} Peering2 Message You Me", AppDomain.CurrentDomain.FriendlyName);
                    return;
                }
            }

            string message = args[0];

            string name = args[1];

            Console.WriteLine("I: preparing broker as {0}", name);

            using (var context = new ZContext())
                using (var cloudFrontend = new ZSocket(context, ZSocketType.ROUTER))
                    using (var cloudBackend = new ZSocket(context, ZSocketType.ROUTER))
                        using (var localFrontend = new ZSocket(context, ZSocketType.ROUTER))
                            using (var localBackend = new ZSocket(context, ZSocketType.ROUTER))
                            {
                                // Bind cloud frontend to endpoint
                                cloudFrontend.IdentityString = name;
                                cloudFrontend.Bind("tcp://127.0.0.1:" + Peering2_GetPort(name) + 0);

                                // Connect cloud backend to all peers
                                cloudBackend.IdentityString = name;
                                for (int i = 2; i < args.Length; ++i)
                                {
                                    string peer = args[i];
                                    Console.WriteLine("I: connecting to cloud frontend at {0}", peer);
                                    cloudBackend.Connect("tcp://127.0.0.1:" + Peering2_GetPort(peer) + 0);
                                }

                                // Prepare local frontend and backend
                                localFrontend.Bind("tcp://127.0.0.1:" + Peering2_GetPort(name) + 1);
                                localBackend.Bind("tcp://127.0.0.1:" + Peering2_GetPort(name) + 2);

                                // Get user to tell us when we can start...
                                Console.WriteLine("Press ENTER when all brokers are started...");
                                Console.ReadKey(true);

                                // Start local workers
                                for (int i = 0; i < Peering2_Workers; ++i)
                                {
                                    int j = i; new Thread(() => Peering2_WorkerTask(context, j, name)).Start();
                                }

                                // Start local clients
                                for (int i = 0; i < Peering2_Clients; ++i)
                                {
                                    int j = i; new Thread(() => Peering2_ClientTask(context, j, name, message)).Start();
                                }

                                // Here, we handle the request-reply flow. We're using load-balancing
                                // to poll workers at all times, and clients only when there are one
                                // or more workers available.

                                // Least recently used queue of available workers
                                var workers = new List <string>();

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

                                while (true)
                                {
                                    // If we have no workers, wait indefinitely
                                    wait = workers.Count > 0 ? (TimeSpan?)TimeSpan.FromMilliseconds(1000) : null;

                                    // Poll localBackend
                                    if (localBackend.PollIn(poll, out incoming, out error, wait))
                                    {
                                        // Handle reply from local worker
                                        string identity = incoming[0].ReadString();
                                        workers.Add(identity);

                                        // If it's READY, don't route the message any further
                                        string hello = incoming[2].ReadString();
                                        if (hello == "READY")
                                        {
                                            incoming.Dispose();
                                            incoming = null;
                                        }
                                    }
                                    else if (error == ZError.EAGAIN && cloudBackend.PollIn(poll, out incoming, out error, wait))
                                    {
                                        // We don't use peer broker identity for anything

                                        // string identity = incoming[0].ReadString();

                                        // string ok = incoming[2].ReadString();
                                    }
                                    else
                                    {
                                        if (error == ZError.ETERM)
                                        {
                                            return;             // Interrupted
                                        }
                                        if (error != ZError.EAGAIN)
                                        {
                                            throw new ZException(error);
                                        }
                                    }

                                    if (incoming != null)
                                    {
                                        // Route reply to cloud if it's addressed to a broker
                                        string identity = incoming[0].ReadString();

                                        for (int i = 2; i < args.Length; ++i)
                                        {
                                            if (identity == args[i])
                                            {
                                                using (incoming)
                                                    cloudFrontend.Send(incoming);

                                                incoming = null;
                                                break;
                                            }
                                        }
                                    }

                                    // Route reply to client if we still need to
                                    if (incoming != null)
                                    {
                                        using (incoming)
                                            localFrontend.Send(incoming);

                                        incoming = null;
                                    }

                                    // Now we route as many client requests as we have worker capacity
                                    // for. We may reroute requests from our local frontend, but not from //
                                    // the cloud frontend. We reroute randomly now, just to test things
                                    // out. In the next version, we'll do this properly by calculating
                                    // cloud capacity://

                                    var rnd = new Random();

                                    while (workers.Count > 0)
                                    {
                                        int reroutable = 0;

                                        // We'll do peer brokers first, to prevent starvation

                                        if (localFrontend.PollIn(poll, out incoming, out error, TimeSpan.FromMilliseconds(64)))
                                        {
                                            reroutable = 0;
                                        }
                                        else if (error == ZError.EAGAIN && cloudFrontend.PollIn(poll, out incoming, out error, TimeSpan.FromMilliseconds(64)))
                                        {
                                            reroutable = 1;
                                        }
                                        else
                                        {
                                            if (error == ZError.ETERM)
                                            {
                                                return;                 // Interrupted
                                            }
                                            if (error == ZError.EAGAIN)
                                            {
                                                break;                  // No work, go back to backends
                                            }
                                            throw new ZException(error);
                                        }

                                        using (incoming)
                                        {
                                            // If reroutable, send to cloud 25% of the time
                                            // Here we'd normally use cloud status information
                                            //
                                            if (reroutable == 1 && rnd.Next(4) == 0)
                                            {
                                                // Route to random broker peer

                                                int peer = rnd.Next(args.Length - 2) + 2;

                                                incoming.ReplaceAt(0, new ZFrame(args[peer]));

                                                /* using (var outgoing = new ZMessage())
                                                 * {
                                                 *      outgoing.Add(new ZFrame(args[peer]));
                                                 *      outgoing.Add(new ZFrame());
                                                 *      outgoing.Add(incoming[2]);
                                                 *
                                                 *      cloudBackend.Send(outgoing);
                                                 * } /**/

                                                cloudBackend.Send(incoming);
                                            }
                                            else
                                            {
                                                // Route to local broker peer

                                                string peer = workers[0];

                                                workers.RemoveAt(0);
                                                incoming.ReplaceAt(0, new ZFrame(peer));

                                                /* using (var outgoing = new ZMessage())
                                                 * {
                                                 *      outgoing.Add(new ZFrame(peer));
                                                 *      outgoing.Add(new ZFrame());
                                                 *      outgoing.Add(incoming[2]);
                                                 *
                                                 *      localBackend.Send(outgoing);
                                                 * } /**/

                                                localBackend.Send(incoming);
                                            }
                                        }
                                    }
                                }
                            }
        }
Esempio n. 12
0
        public static void LBBroker(IDictionary <string, string> dict, string[] args)
        {
            // This is the main task. It starts the clients and workers, and then
            // routes requests between the two layers. Workers signal READY when
            // they start; after that we treat them as ready when they reply with
            // a response back to a client. The load-balancing data structure is
            // just a queue of next available workers.

            // Prepare our context and sockets
            using (var context = new ZContext())
                using (var frontend = new ZSocket(context, ZSocketType.ROUTER))
                    using (var backend = new ZSocket(context, ZSocketType.ROUTER))
                    {
                        // Bind
                        frontend.Bind("inproc://frontend");
                        // Bind
                        backend.Bind("inproc://backend");

                        int clients = 0;
                        for (; clients < LBBroker_Clients; ++clients)
                        {
                            int j = clients;
                            new Thread(() => LBBroker_Client(context, j)).Start();
                        }
                        for (int i = 0; i < LBBroker_Workers; ++i)
                        {
                            int j = i;
                            new Thread(() => LBBroker_Worker(context, j)).Start();
                        }

                        // Here is the main loop for the least-recently-used queue. It has two
                        // sockets; a frontend for clients and a backend for workers. It polls
                        // the backend in all cases, and polls the frontend only when there are
                        // one or more workers ready. This is a neat way to use 0MQ's own queues
                        // to hold messages we're not ready to process yet. When we get a client
                        // reply, we pop the next available worker and send the request to it,
                        // including the originating client identity. When a worker replies, we
                        // requeue that worker and forward the reply to the original client
                        // using the reply envelope.

                        // Queue of available workers
                        var worker_queue = new List <string>();

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

                        while (true)
                        {
                            if (backend.PollIn(poll, out incoming, out error, TimeSpan.FromMilliseconds(64)))
                            {
                                // Handle worker activity on backend

                                // incoming[0] is worker_id
                                string worker_id = incoming[0].ReadString();
                                // Queue worker identity for load-balancing
                                worker_queue.Add(worker_id);

                                // incoming[1] is empty

                                // incoming[2] is READY or else client_id
                                string client_id = incoming[2].ReadString();

                                if (client_id != "READY")
                                {
                                    // incoming[3] is empty

                                    // incoming[4] is reply
                                    string reply = incoming[4].ReadString();

                                    using (var outgoing = new ZMessage())
                                    {
                                        outgoing.Add(new ZFrame(client_id));
                                        outgoing.Add(new ZFrame());
                                        outgoing.Add(new ZFrame(reply));

                                        // Send
                                        frontend.Send(outgoing);
                                    }

                                    if (--clients == 0)
                                    {
                                        // break the while (true) when all clients said Hello
                                        break;
                                    }
                                }
                            }
                            if (worker_queue.Count > 0)
                            {
                                // Poll frontend only if we have available workers

                                if (frontend.PollIn(poll, out incoming, out error, TimeSpan.FromMilliseconds(64)))
                                {
                                    // Here is how we handle a client request

                                    // incoming[0] is client_id
                                    string client_id = incoming[0].ReadString();

                                    // incoming[1] is empty

                                    // incoming[2] is request
                                    string requestText = incoming[2].ReadString();

                                    using (var outgoing = new ZMessage())
                                    {
                                        outgoing.Add(new ZFrame(worker_queue[0]));
                                        outgoing.Add(new ZFrame());
                                        outgoing.Add(new ZFrame(client_id));
                                        outgoing.Add(new ZFrame());
                                        outgoing.Add(new ZFrame(requestText));

                                        // Send
                                        backend.Send(outgoing);
                                    }

                                    // Dequeue the next worker identity
                                    worker_queue.RemoveAt(0);
                                }
                            }
                        }
                    }
        }
Esempio n. 13
0
        public static void LPClient(IDictionary <string, string> dict, string[] args)
        {
            if (args == null || args.Length < 1)
            {
                Console.WriteLine();
                Console.WriteLine("Usage: ./{0} LPClient [Name]", AppDomain.CurrentDomain.FriendlyName);
                Console.WriteLine();
                Console.WriteLine("    Name   Your name. Default: People");
                Console.WriteLine();
                args = new string[] { "People" };
            }

            string name = args[0];

            using (var context = new ZContext())
            {
                ZSocket requester = null;
                try
                {                 // using (requester)
                    ZError error;

                    if (null == (requester = LPClient_CreateZSocket(context, name, out error)))
                    {
                        if (error == ZError.ETERM)
                        {
                            return;                             // Interrupted
                        }
                        throw new ZException(error);
                    }

                    int sequence     = 0;
                    int retries_left = LPClient_RequestRetries;
                    var poll         = ZPollItem.CreateReceiver();

                    while (retries_left > 0)
                    {
                        // We send a request, then we work to get a reply
                        using (var outgoing = ZFrame.Create(4))
                        {
                            outgoing.Write(++sequence);
                            if (!requester.Send(outgoing, out error))
                            {
                                if (error == ZError.ETERM)
                                {
                                    return;                                     // Interrupted
                                }
                                throw new ZException(error);
                            }
                        }

                        ZMessage incoming;
                        while (true)
                        {
                            // Here we process a server reply and exit our loop
                            // if the reply is valid.

                            // If we didn't a reply, we close the client socket
                            // and resend the request. We try a number of times
                            // before finally abandoning:

                            // Poll socket for a reply, with timeout
                            if (requester.PollIn(poll, out incoming, out error, LPClient_RequestTimeout))
                            {
                                using (incoming)
                                {
                                    // We got a reply from the server
                                    int incoming_sequence = incoming[0].ReadInt32();
                                    if (sequence == incoming_sequence)
                                    {
                                        Console.WriteLine("I: server replied OK ({0})", incoming_sequence);
                                        retries_left = LPClient_RequestRetries;
                                        break;
                                    }
                                    else
                                    {
                                        Console_WriteZMessage(incoming, "E: malformed reply from server");
                                    }
                                }
                            }
                            else
                            {
                                if (error == ZError.EAGAIN)
                                {
                                    if (--retries_left == 0)
                                    {
                                        Console.WriteLine("E: server seems to be offline, abandoning");
                                        break;
                                    }

                                    Console.WriteLine("W: no response from server, retrying...");

                                    // Old socket is confused; close it and open a new one
                                    requester.Dispose();
                                    if (null == (requester = LPClient_CreateZSocket(context, name, out error)))
                                    {
                                        if (error == ZError.ETERM)
                                        {
                                            return;                                             // Interrupted
                                        }
                                        throw new ZException(error);
                                    }

                                    Console.WriteLine("I: reconnected");

                                    // Send request again, on new socket
                                    using (var outgoing = ZFrame.Create(4))
                                    {
                                        outgoing.Write(sequence);
                                        if (!requester.Send(outgoing, out error))
                                        {
                                            if (error == ZError.ETERM)
                                            {
                                                return;                                                 // Interrupted
                                            }
                                            throw new ZException(error);
                                        }
                                    }

                                    continue;
                                }

                                if (error == ZError.ETERM)
                                {
                                    return;                                     // Interrupted
                                }
                                throw new ZException(error);
                            }
                        }
                    }
                }
                finally
                {
                    if (requester != null)
                    {
                        requester.Dispose();
                        requester = null;
                    }
                }
            }
        }
Esempio n. 14
0
        public static void Server(ZContext context, String identity, string BrokerAddressforServer, ZSocketType socketType, string AddrForSub)
        {
            using (var server = new ZSocket(context, socketType))
            {
                server.Connect(BrokerAddressforServer);
                server.Identity = Encoding.UTF8.GetBytes(identity);

                string    text = "Confirmed Echo";
                ZPollItem poll = ZPollItem.CreateReceiver();
                ZError    error;
                ZMessage  request2;

                try
                {
                    if (socketType == ZSocketType.REP)
                    {
                        using (ZMessage request = server.ReceiveMessage())
                        {
                            string uid = request[0].ReadString();
                            string receiverIdentity = request[1].ReadString();

                            Console.WriteLine("{0} <- {1} : [{2} {3}]", identity, receiverIdentity, uid, "REQ");

                            Send(server, Encoding.UTF8.GetBytes(identity), text, uid);
                        }
                    }
                    else if (socketType == ZSocketType.PULL)
                    {
                        while (true)
                        {
                            if (server.PollIn(poll, out request2, out error, TimeSpan.FromMilliseconds(1000)))
                            {
                                string uid = request2[1].ReadString();
                                string receivedIdentity = request2[2].ReadString();

                                Console.WriteLine("{0} <- {1} : [{2}]", identity, receivedIdentity, uid);
                            }
                            else
                            {
                                ErrorChecker(error);
                            }
                        }
                    }
                    else if (socketType == ZSocketType.SUB)
                    {
                        if (identity == "Server")
                        {
                            server.Subscribe("B");
                        }
                        if (identity == "Server2")
                        {
                            server.Subscribe("Topic");
                        }
                        if (identity == "Server3")
                        {
                            server.SubscribeAll();
                        }

                        while (true)
                        {
                            using (ZMessage request = server.ReceiveMessage())
                            {
                                string topic            = request[0].ReadString();
                                string uid              = request[1].ReadString();
                                string receivedIdentity = request[2].ReadString();

                                Console.WriteLine("{0} <- {1} : [{2} {3}]", identity, receivedIdentity, uid, topic);
                            }
                        }
                    }
                }
                catch (ZException)
                {
                    context = new ZContext();
                }
            }
        }
Esempio n. 15
0
        protected override async Task ExecuteAsync(CancellationToken ct)
        {
            var endpoints = clusterConfig.Pools.Select(x =>
                                                       x.Extra.SafeExtensionDataAs <BitcoinPoolConfigExtra>()?.BtStream ??
                                                       x.Extra.SafeExtensionDataAs <CryptonotePoolConfigExtra>()?.BtStream)
                            .Where(x => x != null)
                            .DistinctBy(x => $"{x.Url}:{x.SharedEncryptionKey}")
                            .ToArray();

            if (!endpoints.Any())
            {
                return;
            }

            await Task.Run(() =>
            {
                var timeout          = TimeSpan.FromMilliseconds(1000);
                var reconnectTimeout = TimeSpan.FromSeconds(300);

                var relays = endpoints
                             .DistinctBy(x => $"{x.Url}:{x.SharedEncryptionKey}")
                             .ToArray();

                logger.Info(() => "Online");

                while (!ct.IsCancellationRequested)
                {
                    // track last message received per endpoint
                    var lastMessageReceived = relays.Select(_ => clock.Now).ToArray();

                    try
                    {
                        // setup sockets
                        var sockets = relays.Select(SetupSubSocket).ToArray();

                        using (new CompositeDisposable(sockets))
                        {
                            var pollItems = sockets.Select(_ => ZPollItem.CreateReceiver()).ToArray();

                            while (!ct.IsCancellationRequested)
                            {
                                if (sockets.PollIn(pollItems, out var messages, out var error, timeout))
                                {
                                    for (var i = 0; i < messages.Length; i++)
                                    {
                                        var msg = messages[i];

                                        if (msg != null)
                                        {
                                            lastMessageReceived[i] = clock.Now;

                                            using (msg)
                                            {
                                                ProcessMessage(msg);
                                            }
                                        }

                                        else if (clock.Now - lastMessageReceived[i] > reconnectTimeout)
                                        {
                                            // re-create socket
                                            sockets[i].Dispose();
                                            sockets[i] = SetupSubSocket(relays[i]);

                                            // reset clock
                                            lastMessageReceived[i] = clock.Now;

                                            logger.Info(() => $"Receive timeout of {reconnectTimeout.TotalSeconds} seconds exceeded. Re-connecting to {relays[i].Url} ...");
                                        }
                                    }

                                    if (error != null)
                                    {
                                        logger.Error(() => $"{nameof(ShareReceiver)}: {error.Name} [{error.Name}] during receive");
                                    }
                                }
                            }
                        }
                    }

                    catch (Exception ex)
                    {
                        logger.Error(() => $"{nameof(ShareReceiver)}: {ex}");

                        if (!ct.IsCancellationRequested)
                        {
                            Thread.Sleep(1000);
                        }
                    }
                }

                logger.Info(() => "Offline");
            }, ct);
        }
Esempio n. 16
0
        //
        // Broker peering simulation (part 1)
        // Prototypes the state flow
        //
        // Author: metadings
        //

        public static void Peering1(string[] args)
        {
            // First argument is this broker's name
            // Other arguments are our peers' names
            //
            if (args == null || args.Length < 2)
            {
                Console.WriteLine();
                Console.WriteLine("Usage: {0} Peering1 World Receiver0", AppDomain.CurrentDomain.FriendlyName);
                Console.WriteLine("       {0} Peering1 Receiver0 World", AppDomain.CurrentDomain.FriendlyName);
                Console.WriteLine();
                return;
            }
            string self = args[0];

            Console.WriteLine("I: preparing broker as {0}", self);

            using (var context = new ZContext())
                using (var backend = new ZSocket(context, ZSocketType.PUB))
                    using (var frontend = new ZSocket(context, ZSocketType.SUB))
                    {
                        // Bind backend to endpoint
                        backend.Bind("tcp://127.0.0.1:" + Peering1_GetPort(self));

                        // Connect frontend to all peers
                        frontend.SubscribeAll();
                        for (int i = 1; i < args.Length; ++i)
                        {
                            string peer = args[i];
                            Console.WriteLine("I: connecting to state backend at {0}", peer);
                            frontend.Connect("tcp://127.0.0.1:" + Peering1_GetPort(peer));
                        }

                        // The main loop sends out status messages to peers, and collects
                        // status messages back from peers. The zmq_poll timeout defines
                        // our own heartbeat:

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

                        while (true)
                        {
                            // Poll for activity, or 1 second timeout
                            if (!frontend.PollIn(poll, out incoming, out error, TimeSpan.FromSeconds(1)))
                            {
                                if (error == ZError.EAGAIN)
                                {
                                    using (var output = new ZMessage())
                                    {
                                        output.Add(new ZFrame(self));

                                        var outputNumber = ZFrame.Create(4);
                                        outputNumber.Write(rnd.Next(10));
                                        output.Add(outputNumber);

                                        backend.Send(output);
                                    }

                                    continue;
                                }
                                if (error == ZError.ETERM)
                                {
                                    return;
                                }

                                throw new ZException(error);
                            }
                            using (incoming)
                            {
                                string peer_name = incoming[0].ReadString();
                                int    available = incoming[1].ReadInt32();
                                Console.WriteLine("{0} - {1} workers free", peer_name, available);
                            }
                        }
                    }
        }
Esempio n. 17
0
        static void AsyncSrv_Client(ZContext context, int i)
        {
            //
            // Asynchronous client-to-server (DEALER to ROUTER)
            //
            // While this example runs in a single process, that is to make
            // it easier to start and stop the example. Each task has its own
            // context and conceptually acts as a separate process.
            //
            // Authors: Pieter Hintjens, Uli Riehm
            //

            // This is our client task
            // It connects to the server, and then sends a request once per second
            // It collects responses as they arrive, and it prints them out. We will
            // run several client tasks in parallel, each with a different random ID.

            using (var client = ZSocket.Create(context, ZSocketType.DEALER))
            {
                // Set identity to make tracing easier
                client.Identity = Encoding.UTF8.GetBytes("CLIENT" + i);
                // Connect
                client.Connect("tcp://localhost:5570");

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

                int requests = 0;
                while (true)
                {
                    // Tick once per second, pulling in arriving messages
                    for (int centitick = 0; centitick < 100; ++centitick)
                    {
                        if (!client.PollIn(poll, out incoming, out error, TimeSpan.FromMilliseconds(10)))
                        {
                            if (error == ZError.EAGAIN)
                            {
                                error = ZError.None;
                                continue;
                            }
                            if (error == ZError.ETERM)
                            {
                                return;                                 // Interrupted
                            }
                            throw new ZException(error);
                        }
                        using (incoming)
                        {
                            string messageText = incoming[0].ReadString();
                            Console.WriteLine("[CLIENT{0}] {1}", i, messageText);
                        }
                    }
                    using (var outgoing = new ZMessage())
                    {
                        outgoing.Add(new ZFrame(client.Identity));
                        outgoing.Add(new ZFrame("request " + (++requests)));

                        if (!client.Send(outgoing, out error))
                        {
                            if (error == ZError.ETERM)
                            {
                                return;                                 // Interrupted
                            }
                            throw new ZException(error);
                        }
                    }
                }
            }
        }
Esempio n. 18
0
            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);
                        }
                    }
                }
            }
Esempio n. 19
0
        public static void PPWorker(IDictionary <string, string> dict, 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(incoming, "I: receiving reply");

                                    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(incoming, "E: invalid message");
                                    }
                                }
                                else
                                {
                                    Console_WriteZMessage(incoming, "E: invalid message");
                                }
                            }
                            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;
                    }
                }
            }
        }
        public virtual async Task <TResponse> SendAsync <TRequest, TResponse>(string name, Packet <TRequest> packet, IpAddress ip, int port, Func <TResponse, TResponse> successFunction = null, Func <object, TResponse> failureFunction = null, Func <object, TResponse> timeoutFunction = null)
        {
            // Validation
            if (packet == null)
            {
                throw new ArgumentException("packet", string.Format(Messages.ObjectNull, "packet"));
            }
            if (ip == null)
            {
                throw new ArgumentException("ip", string.Format(Messages.ObjectNull, "ip"));
            }
            if (port < 1024)
            {
                throw new ArgumentException("port", Messages.PortNoInRange);
            }
            if (successFunction == null)
            {
                successFunction = OnSuccess;
            }
            if (failureFunction == null)
            {
                failureFunction = OnFailure <TResponse>;
            }
            if (timeoutFunction == null)
            {
                timeoutFunction = OnTimeout <TResponse>;
            }

            using (var context = new ZContext())
            {
                ZSocket requester = null;
                try
                {
                    var createSocketResult = await GetRequestZSocketAsync(context, name, ip, port);

                    if (createSocketResult.Error != ZError.None)
                    {
                        return(failureFunction.Invoke(createSocketResult.Error));
                    }
                    requester = createSocketResult.Socket;
                    int retries_left = RequestRetries;
                    var poll         = ZPollItem.CreateReceiver();
                    while (retries_left > 0)
                    {
                        var json  = JsonConvert.SerializeObject(packet);
                        var frame = new ZFrame(json);
                        if (!requester.Send(frame, out ZError error))
                        {
                            if (error != ZError.None)
                            {
                                return(failureFunction.Invoke(error));
                            }
                        }

                        while (true)
                        {
                            if (requester.PollIn(poll, out ZMessage incomingMessage, out error, RequestTimeout))
                            {
                                using (incomingMessage)
                                {
                                    var responseJson   = incomingMessage[0].ReadString();
                                    var responsePacket = JsonConvert.DeserializeObject <Packet <TResponse> >(responseJson);
                                    retries_left = RequestRetries;
                                    return(successFunction.Invoke(responsePacket.Payload));
                                }
                            }
                            else
                            {
                                if (error == ZError.EAGAIN)
                                {
                                    if (--retries_left == 0)
                                    {
                                        Console.WriteLine($"Worker did not respond: {ip}:{port}.");
                                        break;
                                    }
                                    ;

                                    // Old socket is confused; close it and open a new one
                                    requester.Dispose();
                                    createSocketResult = await GetRequestZSocketAsync(context, name, ip, port);

                                    if (createSocketResult.Error != ZError.None)
                                    {
                                        return(failureFunction.Invoke(createSocketResult.Error));
                                    }
                                    requester = createSocketResult.Socket;
                                    var retryFrame = new ZFrame(json);
                                    if (!requester.Send(retryFrame, out error))
                                    {
                                        if (error != ZError.None)
                                        {
                                            return(failureFunction.Invoke(error));
                                        }
                                    }
                                    continue;
                                }

                                if (error != ZError.None)
                                {
                                    return(failureFunction(error));
                                }
                            }
                        }
                    }
Esempio n. 21
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);
            }
Esempio n. 22
0
        public static void LVCache(string[] args)
        {
            //
            // Last value cache
            // Uses XPUB subscription messages to re-send data
            //
            // Author: metadings
            //

            using (var context = new ZContext())
                using (var frontend = new ZSocket(context, ZSocketType.SUB))
                    using (var backend = new ZSocket(context, ZSocketType.XPUB))
                    {
                        // Subscribe to every single topic from publisher
                        frontend.Connect("tcp://*:5557");
                        frontend.SubscribeAll();

                        backend.Bind("tcp://*:5558");

                        // Store last instance of each topic in a cache
                        var cache = new HashSet <LVCacheItem>();

                        // We route topic updates from frontend to backend, and
                        // we handle subscriptions by sending whatever we cached,
                        // if anything:
                        var      p = ZPollItem.CreateReceiver();
                        ZMessage msg;
                        ZError   error;
                        while (true)
                        {
                            // Any new topic data we cache and then forward
                            if (frontend.PollIn(p, out msg, out error, TimeSpan.FromMilliseconds(1)))
                            {
                                using (msg)
                                {
                                    string topic   = msg[0].ReadString();
                                    string current = msg[1].ReadString();

                                    LVCacheItem previous = cache.FirstOrDefault(item => topic == item.Topic);
                                    if (previous != null)
                                    {
                                        cache.Remove(previous);
                                    }
                                    cache.Add(new LVCacheItem {
                                        Topic = topic, Current = current
                                    });

                                    backend.Send(msg);
                                }
                            }
                            else
                            {
                                if (error == ZError.ETERM)
                                {
                                    break;                      // Interrupted
                                }
                                if (error != ZError.EAGAIN)
                                {
                                    throw new ZException(error);
                                }
                            }

                            // When we get a new subscription, we pull data from the cache:
                            if (backend.PollIn(p, out msg, out error, TimeSpan.FromMilliseconds(1)))
                            {
                                using (msg)
                                {
                                    // Event is one byte 0=unsub or 1=sub, followed by topic
                                    byte subscribe = msg[0].ReadAsByte();
                                    if (subscribe == 0x01)
                                    {
                                        string      topic    = msg[0].ReadString();
                                        LVCacheItem previous = cache.FirstOrDefault(item => topic == item.Topic);
                                        if (previous != null)
                                        {
                                            Console.WriteLine("Sending cached topic {0}", topic);
                                            backend.SendMore(new ZFrame(previous.Topic));
                                            backend.Send(new ZFrame(previous.Current));
                                        }
                                        else
                                        {
                                            Console.WriteLine("Failed to send cached topic {0}!", topic);
                                        }
                                    }
                                }
                            }
                            else
                            {
                                if (error == ZError.ETERM)
                                {
                                    break;                      // Interrupted
                                }
                                if (error != ZError.EAGAIN)
                                {
                                    throw new ZException(error);
                                }
                            }
                        }
                    }
        }
Esempio n. 23
0
        public static void RRBroker(IDictionary <string, string> dict, string[] args)
        {
            //
            // Simple request-reply broker
            //
            // Author: metadings
            //

            // Prepare our context and sockets
            using (var context = new ZContext())
                using (var frontend = new ZSocket(context, ZSocketType.ROUTER))
                    using (var backend = new ZSocket(context, ZSocketType.DEALER))
                    {
                        frontend.Bind("tcp://*:5559");
                        backend.Bind("tcp://*:5560");

                        // Initialize poll set
                        var poll = ZPollItem.CreateReceiver();

                        // Switch messages between sockets
                        ZError   error;
                        ZMessage message;
                        while (true)
                        {
                            if (frontend.PollIn(poll, out message, out error, TimeSpan.FromMilliseconds(64)))
                            {
                                using (message)
                                {
                                    // Process all parts of the message
                                    Console_WriteZMessage(2, message, "frontend");
                                    backend.Send(message);
                                }
                            }
                            else
                            {
                                if (error == ZError.ETERM)
                                {
                                    return;                     // Interrupted
                                }
                                if (error != ZError.EAGAIN)
                                {
                                    throw new ZException(error);
                                }
                            }

                            if (backend.PollIn(poll, out message, out error, TimeSpan.FromMilliseconds(64)))
                            {
                                // Process all parts of the message
                                Console_WriteZMessage(2, message, " backend");
                                frontend.Send(message);
                            }
                            else
                            {
                                if (error == ZError.ETERM)
                                {
                                    return;                     // Interrupted
                                }
                                if (error != ZError.EAGAIN)
                                {
                                    throw new ZException(error);
                                }
                            }
                        }
                    }
        }
Esempio n. 24
0
        private void MainLoop()
        {
            ZError   error;
            ZMessage incoming;
            var      poll = ZPollItem.CreateReceiver();

            while (true)
            {
                //await Task.Delay(1);
                //yield return null;

                if (_backendSocket.PollIn(poll, out incoming, out error, TimeSpan.FromMilliseconds(1)))
                {
                    using (incoming)
                    {
                        // Handle worker activity on backend

                        // incoming[0] is worker_id
                        string workerName = incoming[0].ReadString();
                        // Queue worker identity for load-balancing
                        workerQueue.Add(workerName);

                        // incoming[1] is empty

                        // incoming[2] is READY or else client_id
                        var client_id      = incoming[2];
                        var clientIdString = client_id.ToString();
                        if (client_id.ToString() == "READY")
                        {
                            Logger.Warn("I: ({0}) worker ready!!!", workerName);
                        }
                        else
                        {
                            // incoming[3] is empty
                            // incoming[4] is reply
                            // string reply = incoming[4].ReadString();
                            // int reply = incoming[4].ReadInt32();

                            Logger.Trace("I: ({0}) work complete", workerName);

                            using (var outgoing = new ZMessage())
                            {
                                outgoing.Add(client_id);
                                outgoing.Add(new ZFrame());
                                outgoing.Add(incoming[4]);

                                // Send
                                _responseSocket.Send(outgoing);
                            }
                        }
                    }
                }
                else
                {
                    if (error == ZError.ETERM)
                    {
                        return;
                    }
                    //yield break;
                    if (error != ZError.EAGAIN)
                    {
                        throw new ZException(error);
                    }
                }

                if (workerQueue.Count > 0)
                {
                    // Poll frontend only if we have available workers
                    if (_responseSocket.PollIn(poll, out incoming, out error, TimeSpan.FromMilliseconds(1)))
                    {
                        using (incoming)
                        {
                            // Here is how we handle a client request

                            // Dequeue the next worker identity
                            string workerId = workerQueue[0];
                            workerQueue.RemoveAt(0);

                            // incoming[0] is client_id
                            var client_id   = incoming[0];
                            var clientIdStr = client_id.ToString();
                            // incoming[1] is empty

                            // incoming[2] is request
                            // string request = incoming[2].ReadString();
                            var requestData = incoming[2];

                            Logger.Trace("I: ({0}) working on ({1}) {2}", workerId, client_id, requestData);

                            using (var outgoing = new ZMessage())
                            {
                                outgoing.Add(new ZFrame(workerId));
                                outgoing.Add(new ZFrame());
                                outgoing.Add(client_id);
                                outgoing.Add(new ZFrame());
                                outgoing.Add(requestData);

                                // Send
                                _backendSocket.Send(outgoing);
                            }
                        }
                    }
                    else
                    {
                        if (error == ZError.ETERM)
                        {
                            return;
                        }
                        //yield break;
                        if (error != ZError.EAGAIN)
                        {
                            throw new ZException(error);
                        }
                    }
                }
                else
                {
                    //Logger.Warn("no idle worker....");
                    //AddWorker(); // 不够worker,创建一个
                }
            }
        }
Esempio n. 25
0
        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();
                        }
                    }
        }
Esempio n. 26
0
        // Main function. It is capable of invoking new workers, adding and removing clients and transfering requests and replies between them
        public void Broker()
        {
            ZMessage incoming;
            ZError   error;
            var      poll = ZPollItem.CreateReceiver();

            while (!_stopLoops)
            {
                if (workers_socket.PollIn(poll, out incoming, out error, TimeSpan.FromMilliseconds(64)))
                {
                    string worker_id = incoming[0].ReadString();
                    workers.Add(worker_id);

                    string client_id = incoming[2].ReadString();

                    if (client_id != "READY")
                    {
                        using (var outgoing = new ZMessage())
                        {
                            var response = Serializer.Deserialize <Response>(incoming[4]);
                            var res      = response as ClaimRes;
                            if (res.Ok)
                            {
                                //Console.WriteLine(res.Ok.ToString() + " " + res.Position[0].ToString() + " " + res.Position[1].ToString() + " " + res.UserId.ToString());
                                playfield[res.Position[0] - 1, res.Position[1] - 1] = res.UserId;
                            }

                            outgoing.Add(incoming[2]);
                            outgoing.Add(new ZFrame());
                            outgoing.Add(incoming[4]);

                            users_socket.Send(outgoing);
                            requests++;
                        }
                    }
                }
                if (workers.Count > 0)
                {
                    while (toRemove > 0)
                    {
                        toRemove--;

                        var request = new StartReq()
                        {
                            desire = true
                        };
                        using (var message = new ZMessage())
                            using (var responseStream = new MemoryStream())
                            {
                                message.Add(new ZFrame(workers[0]));
                                message.Add(new ZFrame());
                                message.Add(new ZFrame());
                                message.Add(new ZFrame());

                                Serializer.Serialize(responseStream, request);

                                message.Add(new ZFrame(responseStream.ToArray()));

                                workers_socket.Send(message);
                            }
                        while (workers.Count == 0)
                        {
                            Thread.Sleep(10);
                        }
                    }

                    if (users_socket.PollIn(poll, out incoming, out error, TimeSpan.FromMilliseconds(64)))
                    {
                        using (var receivedFrame = incoming[2])
                        {
                            var request = Serializer.Deserialize <Request>(receivedFrame);
                            //Console.WriteLine(request.RequesType);
                            switch (request.RequesType)
                            {
                            case RequesType.ClaimReq:
                            {
                                using (var outgoing = new ZMessage())
                                {
                                    outgoing.Add(new ZFrame(workers[0]));
                                    outgoing.Add(new ZFrame());
                                    outgoing.Add(incoming[0]);
                                    outgoing.Add(new ZFrame());
                                    outgoing.Add(incoming[2]);

                                    workers_socket.Send(outgoing);
                                }
                                workers.RemoveAt(0);
                                break;
                            }

                            case RequesType.StartReq:
                            {
                                var sr = request as StartReq;
                                //Console.WriteLine(request.RequesType);
                                var response = new StartRes();
                                response.size = size;

                                if (sr.desire)
                                {
                                    if (users.Contains(request.UserId))
                                    {
                                        response.Ok = false;
                                    }
                                    else
                                    {
                                        response.Ok       = true;
                                        response.Position = new List <int>
                                        {
                                            _random.Next(0, size),
                                            _random.Next(0, size)
                                        };
                                        users.Add(request.UserId);
                                        playfield[response.Position[0], response.Position[1]] = request.UserId;
                                        requests++;
                                        if ((users.Count == 2) || (users.Count / 10 > workerCount))
                                        {
                                            Process.Start(workersList[workerCount % workersList.Count], size.ToString() + " " + (++workerCount).ToString() + " " + myAdress);

                                            Console.WriteLine("New worker added, id: " + workerCount);
                                        }
                                        Console.WriteLine("New user added, id: {0}, symbol: {0}", request.UserId);
                                    }
                                }
                                else
                                {
                                    users.Remove(request.UserId);
                                    if (users.Count == 1 || ((users.Count) % 10 == 0 && users.Count > 0))
                                    {
                                        toRemove++;
                                    }
                                    Console.WriteLine("User removed, id: {0}, symbol: {0}", request.UserId);
                                    response.Ok = true;
                                    for (int i = 0; i < size; ++i)
                                    {
                                        for (int j = 0; j < size; ++j)
                                        {
                                            if (playfield[i, j] == request.UserId)
                                            {
                                                playfield[i, j] = 0;
                                            }
                                        }
                                    }
                                }
                                using (var responseStream = new MemoryStream())
                                    using (var outgoing = new ZMessage())
                                    {
                                        Serializer.Serialize(responseStream, response);

                                        outgoing.Add(incoming[0]);
                                        outgoing.Add(new ZFrame());
                                        outgoing.Add(new ZFrame(responseStream.ToArray()));

                                        users_socket.Send(outgoing);
                                    }

                                break;
                            }
                            }
                        }
                    }
                }
            }
        }
Esempio n. 27
0
        private void StartMessageReceiver(ZmqPubSubEndpointConfig[] endpoints)
        {
            Task.Run(() =>
            {
                Thread.CurrentThread.Name = "BtStreamReceiver Socket Poller";
                var timeout          = TimeSpan.FromMilliseconds(1000);
                var reconnectTimeout = TimeSpan.FromSeconds(300);

                var relays = endpoints
                             .DistinctBy(x => $"{x.Url}:{x.SharedEncryptionKey}")
                             .ToArray();

                while (!cts.IsCancellationRequested)
                {
                    // track last message received per endpoint
                    var lastMessageReceived = relays.Select(_ => clock.UtcNow).ToArray();

                    try
                    {
                        // setup sockets
                        var sockets = relays.Select(SetupSubSocket).ToArray();

                        using (new CompositeDisposable(sockets))
                        {
                            var pollItems = sockets.Select(_ => ZPollItem.CreateReceiver()).ToArray();

                            while (!cts.IsCancellationRequested)
                            {
                                if (sockets.PollIn(pollItems, out var messages, out var error, timeout))
                                {
                                    for (var i = 0; i < messages.Length; i++)
                                    {
                                        var msg = messages[i];

                                        if (msg != null)
                                        {
                                            lastMessageReceived[i] = clock.UtcNow;

                                            using (msg)
                                            {
                                                ProcessMessage(msg);
                                            }
                                        }

                                        else if (clock.UtcNow - lastMessageReceived[i] > reconnectTimeout)

                                        {
                                            // re-create socket
                                            sockets[i].Dispose();
                                            sockets[i] = SetupSubSocket(relays[i]);

                                            // reset clock
                                            lastMessageReceived[i] = clock.UtcNow;

                                            logger.Info(() => $"Receive timeout of {reconnectTimeout.TotalSeconds} seconds exceeded. Re-connecting to {relays[i].Url} ...");
                                        }
                                    }

                                    if (error != null)
                                    {
                                        logger.Error(() => $"{nameof(ShareReceiver)}: {error.Name} [{error.Name}] during receive");
                                    }
                                }
                            }
                        }
                    }

                    catch (Exception ex)
                    {
                        logger.Error(() => $"{nameof(ShareReceiver)}: {ex}");

                        if (!cts.IsCancellationRequested)
                        {
                            Thread.Sleep(1000);
                        }
                    }
                }
            }, cts.Token);
        }
Esempio n. 28
0
            public ZMessage Request(ZMessage request)
            {
                // This method does the hard work. It sends a request to all
                // connected servers in parallel (for this to work, all connections
                // must be successful and completed by this time). It then waits
                // for a single successful reply, and returns that to the caller.
                // Any other replies are just dropped:

                ZMessage reply = null;

                using (request)
                {
                    // Prefix request with sequence number and empty envelope
                    this.sequence++;
                    request.Prepend(new ZFrame(this.sequence));
                    request.Prepend(new ZFrame());

                    // Blast the request to all connected servers
                    for (int server = 0; server < this.servers; ++server)
                    {
                        using (var outgoing = request.Duplicate())
                        {
                            this.socket.Send(outgoing);
                        }
                    }

                    // Wait for a matching reply to arrive from anywhere
                    // Since we can poll several times, calculate each one
                    ZError   error;
                    DateTime endtime = DateTime.UtcNow + GLOBAL_TIMEOUT;
                    var      poll    = ZPollItem.CreateReceiver();
                    while (endtime > DateTime.UtcNow)
                    {
                        if (this.socket.PollIn(poll, out reply, out error, endtime - DateTime.UtcNow))
                        {
                            // Reply is [empty][sequence][OK]
                            if (reply.Count < 3)
                            {
                                throw new InvalidOperationException();
                            }

                            reply.RemoveAt(0);

                            using (ZFrame sequenceFrame = reply.RemoveAt(0, false))
                            {
                                int sequence = sequenceFrame.ReadInt32();

                                if (sequence == this.sequence)
                                {
                                    break;                                      // Reply is ok
                                }
                            }

                            reply.Dispose();
                        }
                        else
                        {
                            if (error == ZError.ETERM)
                            {
                                break;                                  // Interrupted
                            }
                            if (error != ZError.EAGAIN)
                            {
                                throw new ZException(error);
                            }
                        }
                    }
                }
                return(reply);
            }
Esempio n. 29
0
        private ZFrame SendMess(ZFrame frame)
        {
            replay = null;
            ZError   error;
            ZMessage msg = null;

            using (var requesterMorph = new ZSocket(ZSocketType.REQ))
            //using (var requesterDB = new ZSocket(ZSocketType.REQ))
            {
                // Connect
                requesterMorph.Connect("tcp://127.0.0.1:5559");
                //requesterDB.Connect("tcp://127.0.0.1:5560");

                var poll = ZPollItem.CreateReceiver();

                // Send
                switch (this.servType)
                {
                case ServType.svMorph:
                    requesterMorph.Send(frame);
                    break;

                case ServType.svSUBD:
                    //requesterDB.Send(frame);
                    break;
                }

                // Process messages from both sockets
                if (requesterMorph.PollIn(poll, out msg, out error, TimeSpan.FromMilliseconds(5000)))
                //if (requesterMorph.PollIn(poll, out msg, out error))
                {
                    // Process task
                    replay = msg[0];
                }
                else
                {
                    if (error == ZError.ETERM)
                    {
                        return(replay);                           // Interrupted
                    }
                    if (error != ZError.EAGAIN)
                    {
                        throw new ZException(error);
                    }
                }

                /*if (requesterDB.PollIn(poll, out msg, out error, TimeSpan.FromMilliseconds(10000)))
                 * {
                 *      // Process task
                 *      replay = msg[0];
                 * }
                 * else
                 * {
                 *      if (error == ZError.ETERM)
                 *              return replay;    // Interrupted
                 *      if (error != ZError.EAGAIN)
                 *              throw new ZException(error);
                 * }*/

                /*/ Receive
                 * using (ZFrame reply = requesterMorph.ReceiveFrame())
                 * {
                 *      reply.Position = 0;
                 *      var bufrep = reply.Read();
                 *      //PrintRep(bufrep);
                 *      replay = GetRep(bufrep);
                 * }*/
            }

            return(replay);
        }
Esempio n. 30
0
        static void Main(string[] args)
        {
            //
            // Simple Pirate broker
            // This is identical to load-balancing pattern, with no reliability
            // mechanisms. It depends on the client for recovery. Runs forever.
            //
            // Author: metadings
            //

            using (var context = new ZContext())
                using (var frontend = new ZSocket(context, ZSocketType.ROUTER))
                    using (var backend = new ZSocket(context, ZSocketType.ROUTER))
                    {
                        frontend.Bind("tcp://*:5555");
                        backend.Bind("tcp://*:5556");

                        // Queue of available workers
                        var worker_queue = new List <string>();

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

                        while (true)
                        {
                            if (backend.PollIn(poll, out incoming, out error, TimeSpan.FromMilliseconds(64)))
                            {
                                using (incoming)
                                {
                                    incoming.DumpZmsg("-----from worker------");

                                    /*
                                     * [2016-09-11T20:13:38:3787670 +08:00] - -----from worker------
                                     * [2016-09-11T20:13:38:3797682 +08:00] -  D: [008]:Worker-1
                                     * [2016-09-11T20:13:38:3807673 +08:00] -  D: [000]:
                                     * [2016-09-11T20:13:38:3807673 +08:00] -  D: [004]:MIKE
                                     * [2016-09-11T20:13:38:3817685 +08:00] -  D: [000]:
                                     * [2016-09-11T20:13:38:3817685 +08:00] -  D: [004]:02000000
                                     */
                                    // Handle worker activity on backend

                                    // incoming[0] is worker_id
                                    string worker_id = incoming[0].ReadString();
                                    // Queue worker identity for load-balancing
                                    worker_queue.Add(worker_id);

                                    // incoming[1] is empty

                                    // incoming[2] is READY or else client_id
                                    string client_id = incoming[2].ReadString();

                                    if (client_id == "READY")
                                    {
                                        Console.WriteLine("I: ({0}) worker ready", worker_id);
                                    }
                                    else
                                    {
                                        // incoming[3] is empty

                                        // incoming[4] is reply
                                        // string reply = incoming[4].ReadString();
                                        // int reply = incoming[4].ReadInt32();

                                        Console.WriteLine("I: ({0}) work complete", worker_id);

                                        using (var outgoing = new ZMessage())
                                        {
                                            // repackaging message
                                            outgoing.Add(new ZFrame(client_id));
                                            outgoing.Add(new ZFrame());
                                            outgoing.Add(incoming[4]);

                                            // Send to client
                                            frontend.Send(outgoing);
                                        }
                                    }
                                }
                            }
                            else
                            {
                                if (error == ZError.ETERM)
                                {
                                    return;
                                }
                                if (error != ZError.EAGAIN)
                                {
                                    throw new ZException(error);
                                }
                            }

                            if (worker_queue.Count > 0)
                            {
                                // Poll frontend only if we have available workers

                                if (frontend.PollIn(poll, out incoming, out error, TimeSpan.FromMilliseconds(64)))
                                {
                                    using (incoming)
                                    {
                                        // Here is how we handle a client request

                                        // Dequeue the next worker identity
                                        string worker_id = worker_queue[0];
                                        worker_queue.RemoveAt(0);

                                        incoming.DumpZmsg("-------from client---------");
                                        // incoming[0] is client_id
                                        string client_id = incoming[0].ReadString();

                                        // incoming[1] is empty

                                        // incoming[2] is request
                                        // string request = incoming[2].ReadString();
                                        int request = incoming[2].ReadInt32();

                                        Console.WriteLine("I: ({0}) working on ({1}) {2}", worker_id, client_id, request);

                                        using (var outgoing = new ZMessage())
                                        {
                                            outgoing.Add(new ZFrame(worker_id));
                                            outgoing.Add(new ZFrame());
                                            outgoing.Add(new ZFrame(client_id));
                                            outgoing.Add(new ZFrame());
                                            outgoing.Add(incoming[2]);

                                            // Send
                                            backend.Send(outgoing);
                                        }
                                    }
                                }
                                else
                                {
                                    if (error == ZError.ETERM)
                                    {
                                        return;
                                    }
                                    if (error != ZError.EAGAIN)
                                    {
                                        throw new ZException(error);
                                    }
                                }
                            }
                        }
                    }
        }