AddTimer() 공개 메소드

Add the given timer to this Poller's list.
timer must not be null. This poller must not have already been disposed.
public AddTimer ( [ timer ) : void
timer [ the NetMQTimer to add to the list
리턴 void
예제 #1
0
        public static void Run()
        {
            using (NetMQContext context = NetMQContext.Create())
            {
                using (var publisherSocket = context.CreateXPublisherSocket())
                {
                    publisherSocket.SetWelcomeMessage("WM");
                    publisherSocket.Bind("tcp://*:6669");

                    // we just drop subscriptions
                    publisherSocket.ReceiveReady += (sender, eventArgs) => publisherSocket.SkipMultipartMessage();

                    Poller poller = new Poller(publisherSocket);

                    // send a message every second
                    NetMQTimer sendMessageTimer = new NetMQTimer(1000);
                    poller.AddTimer(sendMessageTimer);
                    sendMessageTimer.Elapsed +=
                        (sender, eventArgs) =>
                            publisherSocket.SendMoreFrame("A").SendFrame(new Random().Next().ToString());

                    // send heartbeat every two seconds
                    NetMQTimer heartbeatTimer = new NetMQTimer(2000);
                    poller.AddTimer(heartbeatTimer);
                    heartbeatTimer.Elapsed += (sender, eventArgs) => publisherSocket.SendFrame("HB");

                    poller.PollTillCancelled();
                }
            }
        }
            public void RunPipeline(PairSocket shim)
            {
                publisherSocket = context.CreatePublisherSocket();
                publisherSocket.Bind("tcp://*:" + StreamingProtocol.Port);

                snapshotSocket = context.CreateResponseSocket();
                snapshotSocket.Bind("tcp://*:" + SnapshotProtocol.Port);
                snapshotSocket.ReceiveReady += OnSnapshotReady;

                shim.ReceiveReady += OnShimReady;

                heartbeatTimer          = new NetMQTimer(StreamingProtocol.HeartbeatInterval);
                heartbeatTimer.Elapsed += OnHeartbeatTimerElapsed;

                shim.SignalOK();

                poller = new Poller();
                poller.AddSocket(shim);
                poller.AddSocket(snapshotSocket);
                poller.AddTimer(heartbeatTimer);
                poller.Start();

                publisherSocket.Dispose();
                snapshotSocket.Dispose();
            }
예제 #3
0
        public void Run(params string[] addresses)
        {
            using (m_context = NetMQContext.Create())
              {
            var subscriber = Connect(addresses);

            if (subscriber == null)
              throw new Exception("cannot connect to eny of the endpoints");

            // timeout timer, when heartbeat was not arrived for 5 seconds
            m_timeoutTimer = new NetMQTimer(TimeSpan.FromSeconds(5));
            m_timeoutTimer.Elapsed += (sender, args) =>
            {
              // timeout happend, first dispose existing subscriber
              subscriber.Dispose();
              m_poller.RemoveSocket(subscriber);

              // connect again
              subscriber = Connect(addresses);

              if (subscriber == null)
            throw new Exception("cannot connect to eny of the endpoints");

              m_poller.AddSocket(subscriber);
            };

            m_poller = new Poller(subscriber);
            m_poller.AddTimer(m_timeoutTimer);

            m_poller.PollTillCancelled();
              }
        }
예제 #4
0
        void IShimHandler.Run(PairSocket shim)
        {
            _pipe = shim;
            _pipe.SignalOK();
            _pipe.ReceiveReady += OnPipeReady;

            _timer = new NetMQTimer(TimeSpan.FromSeconds(1));
            _timer.Elapsed += OnPingPeer;

            _inbox = _context.CreateRouterSocket();
            _inbox.ReceiveReady += OnInboxReady;

            _poller = new Poller(_pipe);
            _poller.AddTimer(_timer);
            _poller.PollTillCancelled();
        }
예제 #5
0
        /// <summary>
        ///     run the broker - if not bound to endpoint automatically binds to known endpoint
        /// </summary>
        /// <param name="token">CancellationToken to cancel the method</param>
        /// <exception cref="InvalidOperationException">Can't start same broker more than once!</exception>
        public void RunSynchronous(CancellationToken token)
        {
            if (m_isRunning)
            {
                throw new InvalidOperationException("Can't start same broker more than once!");
            }

            if (!m_isBound)
            {
                Bind();
            }

            m_isRunning = true;

            using (var poller = new NetMQ.Poller())
            {
                Socket.ReceiveReady += ProcessReceiveMessage;
                // get timer for scheduling heartbeat
                var timer = new NetMQTimer(HeartbeatInterval);
                // send every 'HeartbeatInterval' a heartbeat to all not expired workers
                timer.Elapsed += (s, e) => SendHeartbeat();

                poller.AddSocket(Socket);
                poller.AddTimer(timer);

                Log("[BROKER] Starting to listen for incoming messages ...");

                // start the poller and wait for the return, which will happen once token is
                // signalling Cancel(!)
                Task.Factory.StartNew(poller.Start, token).Wait();

                Log("[BROKER] ... Stopped!");

                // clean up
                poller.RemoveTimer(timer);
                poller.RemoveSocket(Socket);
                // unregister event handler
                Socket.ReceiveReady -= ProcessReceiveMessage;
            }

            m_isRunning = false;
        }
예제 #6
0
        static void Main(string[] args)
        {
            using (var context = NetMQContext.Create())
            {
                string[] topics = new string[] { "A", "B", "C" };
                Random random = new Random();

                using (var publisher = context.CreateXPublisherSocket())
                {
                    // Set publisher to manual subscriptions mode
                    publisher.Options.ManualPublisher = true;
                    publisher.Bind("tcp://*:5556");
                    publisher.ReceiveReady += (sender, eventArgs) =>
                    {
                        var message = publisher.ReceiveString();

                        // we only handle subscription requests, unsubscription and any
                        // other type of messages will be dropped
                        if (message[0] == (char)1)
                        {
                            // calling Subscribe to add subscription to the last subscriber
                            publisher.Subscribe(message.Substring(1));
                        }
                    };

                    NetMQTimer sendTimer = new NetMQTimer(1000);
                    sendTimer.Elapsed += (sender, eventArgs) =>
                    {
                        // sends a message every second with random topic and current time
                        publisher.
                            SendMore(topics[random.Next(3)]).
                            Send(DateTime.Now.ToString());
                    };

                    Poller poller = new Poller();
                    poller.AddSocket(publisher);
                    poller.AddTimer(sendTimer);
                    poller.PollTillCancelled();
                }
            }
        }
            public void RunPipeline(PairSocket shim)
            {
                // we should signal before running the poller but this will block the application
                shim.SignalOK();

                this.poller = new Poller();

                shim.ReceiveReady += OnShimReady;
                poller.AddSocket(shim);

                timeoutTimer          = new NetMQTimer(StreamingProtocol.Timeout);
                timeoutTimer.Elapsed += TimeoutElapsed;
                poller.AddTimer(timeoutTimer);

                Connect();

                poller.Start();

                if (subscriberSocket != null)
                {
                    subscriberSocket.Dispose();
                }
            }
예제 #8
0
            public void Run(PairSocket shim)
            {
                m_pipe = shim;

                shim.SignalOK();

                m_pipe.ReceiveReady += OnPipeReady;

                m_pingTimer          = new NetMQTimer(0);
                m_pingTimer.Elapsed += PingElapsed;
                m_pingTimer.Enable   = false;

                m_poller = new Poller();
                m_poller.AddSocket(m_pipe);
                m_poller.AddTimer(m_pingTimer);

                m_poller.PollTillCancelled();

                // the beacon might never been configured
                if (m_udpSocket != null)
                {
                    m_udpSocket.Close();
                }
            }
예제 #9
0
        static void Main(string[] args)
        {
            // this key should be shared between authorization server and publisher
              const string Key = "SecretKey";

              string[] symbols = new[] {"EURUSD", "GBPUSD", "EURJPY",
            "USDJPY", "EURGBP", "GBPJPY"};

              Random random = new Random();

              using (var context = NetMQContext.Create())
              {
            using (var publisher = context.CreateXPublisherSocket())
            {
              publisher.Options.ManualPublisher = true;
              publisher.Bind("tcp://*:5558");
              publisher.ReceiveReady += (sender, eventArgs) =>
              {
            byte[] subscriptionBytes = publisher.Receive();

            if (subscriptionBytes[0] == 1 || subscriptionBytes[0] == 0)
            {
              // the rest of the bytes is the token, convert them to string
              string serializedToken = Encoding.ASCII.GetString(
                  subscriptionBytes, 1, subscriptionBytes.Length - 1);

              // deserialize the token
              Token token;

              if (Token.TryDeserialize(serializedToken, out token))
              {
                // Check if the token is valid
                if (token.Validate(Key))
                {
                  // first byte indicate if it a subscription or unsubscription
                  if (subscriptionBytes[0] == 1)
                  {
                    Console.WriteLine("Subscription request {0}",
                        token.Subscription);
                    publisher.Subscribe(token.Subscription);
                  }
                  else
                  {
                    publisher.Unsubscribe(token.Subscription);
                  }
                }
                else
                {
                  Console.WriteLine("Invalid token {0}",
                      serializedToken);
                }
              }
            }
              };

              // Some fake publishing
              NetMQTimer publishTimer = new NetMQTimer(100);
              publishTimer.Elapsed += (sender, eventArgs) =>
              {
            publisher.
                SendMore(symbols[random.Next(symbols.Length)]).
                Send(random.Next().ToString());
              };

              Poller poller = new Poller();
              poller.AddSocket(publisher);
              poller.AddTimer(publishTimer);
              poller.PollTillCancelled();
            }
              }
        }
예제 #10
0
파일: MDPBroker.cs 프로젝트: romanros/netmq
        /// <summary>
        ///     run the broker - if not bound to endpoint automatically binds to known endpoint 
        /// </summary>
        /// <param name="token">CancellationToken to cancel the method</param>
        /// <exception cref="InvalidOperationException">Can't start same broker more than once!</exception>
        public void RunSynchronous (CancellationToken token)
        {
            if (m_isRunning)
                throw new InvalidOperationException ("Can't start same broker more than once!");

            if (!m_isBound)
                Bind ();

            m_isRunning = true;

            using (var poller = new Poller ())
            {
                Socket.ReceiveReady += ProcessReceivedMessage;
                // get timer for scheduling heartbeat
                var timer = new NetMQTimer (HeartbeatInterval);
                // send every 'HeartbeatInterval' a heartbeat to all not expired workers
                timer.Elapsed += (s, e) => SendHeartbeat ();

                poller.AddSocket (Socket);
                poller.AddTimer (timer);

                Log ("Starting to listen for incoming messages ...");

                // start the poller and wait for the return, which will happen once token is 
                // signalling Cancel(!)
                Task.Factory.StartNew (poller.PollTillCancelled, token).Wait ();

                Log ("... Stopped!");

                // clean up
                poller.RemoveTimer (timer);
                poller.RemoveSocket (Socket);
                // unregister event handler
                Socket.ReceiveReady -= ProcessReceivedMessage;
            }

            m_isRunning = false;
        }
예제 #11
0
            public void Run(PairSocket shim)
            {
                m_pipe = shim;

                shim.SignalOK();

                m_pipe.ReceiveReady += OnPipeReady;

                m_pingTimer = new NetMQTimer(0);
                m_pingTimer.Elapsed += PingElapsed;
                m_pingTimer.Enable = false;

                m_poller = new Poller();
                m_poller.AddSocket(m_pipe);
                m_poller.AddTimer(m_pingTimer);

                m_poller.PollTillCancelled();

                // the beacon might never been configured
                if (m_udpSocket != null)
                {
                    m_udpSocket.Close();
                }
            }
예제 #12
0
        private void Connect()
        {
            List<SubscriberSocket> sockets = new List<SubscriberSocket>();
            Poller poller = new Poller();

            SubscriberSocket connectedSocket = null;

            // event handler to handle message from socket
            EventHandler<NetMQSocketEventArgs> handleMessage = (sender, args) =>
            {
                connectedSocket = (SubscriberSocket)args.Socket;
                poller.Cancel();
            };

            NetMQTimer timeoutTimer = new NetMQTimer(TimeOut);

            // just cancel the poller without seting the connected socket
            timeoutTimer.Elapsed += (sender, args) => poller.Cancel();
            poller.AddTimer(timeoutTimer);

            foreach (var address in m_addresses)
            {
                var socket = m_context.CreateSubscriberSocket();
                sockets.Add(socket);

                socket.ReceiveReady += handleMessage;
                poller.AddSocket(socket);

                // Subscribe to welcome message
                socket.Subscribe(WelcomeMessage);
                socket.Connect(address);
            }

            poller.PollTillCancelled();

            // if we a connected socket the connection attempt succeed
            if (connectedSocket != null)
            {
                // remove the connected socket form the list
                sockets.Remove(connectedSocket);

                // close all exsiting connections
                foreach (var socket in sockets)
                {
                    // to close them immediatly we set the linger to zero
                    socket.Options.Linger = TimeSpan.Zero;
                    socket.Dispose();
                }

                // set the socket
                m_subscriber = connectedSocket;

                // drop the welcome message
                m_subscriber.SkipMultipartMessage();

                // subscribe to heartbeat
                m_subscriber.Subscribe(HeartbeatMessage);

                // subscribe to all subscriptions
                foreach (string subscription in m_subscriptions)
                {
                    m_subscriber.Subscribe(subscription);
                }

                m_subscriber.ReceiveReady -= handleMessage;
                m_subscriber.ReceiveReady += OnSubscriberMessage;
                m_poller.AddSocket(m_subscriber);

                m_timeoutTimer.Enable = true;
                m_reconnectTimer.Enable = false;
            }
            else
            {
                // close all exsiting connections
                foreach (var socket in sockets)
                {
                    // to close them immediatly we set the linger to zero
                    socket.Options.Linger = TimeSpan.Zero;
                    socket.Dispose();
                }

                m_reconnectTimer.Enable = true;
                m_timeoutTimer.Enable = false;
            }
        }
예제 #13
0
        private void Run(PairSocket shim)
        {
            m_shim = shim;
            shim.ReceiveReady += OnShimMessage;

            m_timeoutTimer = new NetMQTimer(TimeOut);
            m_timeoutTimer.Elapsed += OnTimeoutTimer;

            m_reconnectTimer = new NetMQTimer(ReconnectTimer);
            m_reconnectTimer.Elapsed += OnReconnectTimer;

            m_poller = new Poller(shim);
            m_poller.AddTimer(m_timeoutTimer);
            m_poller.AddTimer(m_reconnectTimer);

            shim.SignalOK();

            Connect();

            m_poller.PollTillCancelled();

            if (m_subscriber != null)
                m_subscriber.Dispose();
        }
예제 #14
0
        /// <summary>
        ///     the broker setting up the cluster
        /// 
        /// 
        ///          State 2 ---+         +--- State n
        ///                     |         |
        ///                     +----+----+
        ///     client 1 ---|        |         |--- worker 1
        ///     client 2 ---+---- BROKER 1 ----+--- worker 2
        ///     :           |        |         |    :
        ///     client n ---+   +----+----+    +--- worker n
        ///                     |         |
        ///                  BROKER 2   BROKER n
        /// 
        ///     BROKER 2 and n are not included and must be setup separately
        /// 
        ///     A minimum of two address must be supplied
        /// </summary>
        /// <param name="args">[0] = this broker's address
        ///                    [1] = 1st peer's address
        ///                     :
        ///                    [n] = nth peer address</param>
        /// <remarks>
        ///     since "inproc://" is not working in NetMQ we use "tcp://"
        ///     for each broker we need 5 ports which for this example are
        ///     assigned as follows (in true life it should be configurable whether 
        ///     they are ports or tcp/ip addresses)
        /// 
        ///     this brokers address => local frontend binds to     tcp://127.0.0.1:5555
        ///                             cloud frontend binds to                    :5556
        ///                             local backend binds to                     :5557
        ///                             state backend binds to                     :5558
        ///                             monitor PULL binds to                      :5559
        /// 
        ///     the sockets are connected as follows
        /// 
        ///               this broker's monitor PUSH connects to    tcp://127.0.0.1:5559
        /// 
        ///                         (if peer's address and port is  tcp://127.0.0.1:5575)
        ///             
        ///               this broker's cloud backend connects to                  :5576
        ///               this broker's state frontend connects to                 :5578
        /// 
        ///     this scheme is fix in this example
        /// </remarks>
        public static void Main(string[] args)
        {
            Console.Title = "NetMQ Inter-Broker Router";

            const string baseAddress = "tcp://127.0.0.1:";

            if (args.Length < 2)
            {
                Console.WriteLine("usage: program me peer1 [peer]*");
                Console.WriteLine("each broker needs 5 port for his sockets!");
                Console.WriteLine("place enough distance between multiple broker addresses!");
                Environment.Exit(-1);
            }

            // trapping Ctrl+C as exit signal!
            Console.CancelKeyPress += (s, e) =>
            {
                e.Cancel = true;
                s_keepRunning = false;
            };

            // get random generator for later use
            var rnd = new Random();
            // get list for registering the clients
            var clients = new List<byte[]>(NbrClients);
            // get a list of peer addresses
            var peers = new List<byte[]>();
            // get all peer addresses - first is this broker!
            for (var i = 1; i < args.Length; i++)
                peers.Add(Encoding.UTF8.GetBytes(args[i]));

            // build this broker's address
            var me = baseAddress + args[0];
            // get the port as integer for later use
            var myPort = int.Parse(args[0]);

            Console.WriteLine("[BROKER] The broker can be stopped by using CTRL+C!");
            Console.WriteLine("[BROKER] setting up sockets ...");

            // set up all the addresses needed in the due course
            var localFrontendAddress = me;
            var cloudFrontendAddress = baseAddress + (myPort + 1);
            var localBackendAddress = baseAddress + (myPort + 2);
            var stateBackendAddress = baseAddress + (myPort + 3);
            var monitorAddress = baseAddress + (myPort + 4);

            // create the context and all the sockets
            using (var context = NetMQContext.Create())
            using (var localFrontend = context.CreateRouterSocket())
            using (var localBackend = context.CreateRouterSocket())
            using (var cloudFrontend = context.CreateRouterSocket())
            using (var cloudBackend = context.CreateRouterSocket())
            using (var stateBackend = context.CreatePublisherSocket())
            using (var stateFrontend = context.CreateSubscriberSocket())
            using (var monitor = context.CreatePullSocket())
            {
                // give every socket an unique identity, e.g. LocalFrontend[Port]
                SetIdentities(myPort,
                    localFrontend,
                    cloudFrontend,
                    localBackend,
                    stateBackend,
                    monitor,
                    cloudBackend, stateFrontend);

                // subscribe to any message on the stateFrontend socket!
                stateFrontend.Subscribe("");

                // bind the serving sockets
                localFrontend.Bind(localFrontendAddress);
                cloudFrontend.Bind(cloudFrontendAddress);
                localBackend.Bind(localBackendAddress);
                stateBackend.Bind(stateBackendAddress);
                monitor.Bind(monitorAddress);

                // connect sockets to peers
                for (var i = 1; i < args.Length; i++)
                {
                    // build the cloud back end address
                    var peerPort = int.Parse(args[i]);
                    var address = baseAddress + (peerPort + 1);
                    Console.WriteLine("[BROKER] connect to cloud peer {0}", address);

                    // this cloudBackend connects to all peer cloudFrontends
                    cloudBackend.Connect(address);

                    // build the state front end address
                    address = baseAddress + (peerPort + 3);
                    Console.WriteLine("[BROKER] subscribe to state peer {0}", address);

                    // this stateFrontend to all peer stateBackends
                    stateFrontend.Connect(address);
                }

                // setup the local worker queue for LRU and monitor cloud capacity
                var workerQueue = new Queue<byte[]>();
                int previousLocalCapacity = 0;

                // receive the capacity available from other peer(s)
                stateFrontend.ReceiveReady += (s, e) =>
                {
                    // the message should contain the available cloud capacity
                    var capacity = e.Socket.ReceiveFrameString();

                    Debug.Assert(string.IsNullOrWhiteSpace(capacity), "StateFrontend: message was empty!");

                    int couldCapacity;
                    Debug.Assert(int.TryParse(capacity, out couldCapacity), "StateFrontend: message did not contain a number!");
                };

                // get the status message and print it
                monitor.ReceiveReady += (s, e) =>
                {
                    var msg = e.Socket.ReceiveFrameString();

                    Console.WriteLine("[MONITOR] {0}", msg);
                };

                // all local clients are connecting to this socket
                // they send a REQ and get a REPLY
                localFrontend.ReceiveReady += (s, e) =>
                {
                    // [client adr][empty][message id]
                    var request = e.Socket.ReceiveMultipartMessage();
                    // register the local client for later identification if not known
                    if (!clients.Any(n => AreSame(n, request[0])))
                        clients.Add(request[0].Buffer);
                    // if we have local capacity send worker else send to cloud
                    if (workerQueue.Count > 0)
                    {
                        // get the LRU worker adr
                        var worker = workerQueue.Dequeue();
                        // wrap message with workers address
                        var msg = Wrap(worker, request);
                        // send message to the worker
                        // [worker adr][empty][client adr][empty][data]
                        localBackend.SendMessage(msg);
                    }
                    else
                    {
                        // get an random index for peers
                        var peerIdx = rnd.Next(peers.Count - 2) + 2;
                        // get peers address
                        var peer = peers[peerIdx];
                        // wrap message with peer's address
                        var msg = Wrap(peer, request);
                        // [peer adr][empty][client adr][empty][data]
                        cloudBackend.SendMessage(msg);
                    }
                };

                // the workers are connected to this socket
                // we get a REPLY either for a cloud client [worker adr][empty][peer adr][empty][peer client adr][empty][data]
                // or local client [worker adr][empty][client adr][empty][data]
                // or a READY message [worker adr][empty][WORKER_READY]
                localBackend.ReceiveReady += (s, e) =>
                {
                    // a worker can send "READY" or a request
                    // or an REPLAY
                    var msg = e.Socket.ReceiveMultipartMessage();

                    // just to make sure we received a proper message
                    Debug.Assert(msg != null && msg.FrameCount > 0, "[LocalBackend] message was empty or frame count == 0!");

                    // get the workers identity
                    var id = Unwrap(msg);
                    // this worker done in either way so add it to available workers
                    workerQueue.Enqueue(id);
                    // if it is NOT a ready message we need to route the message
                    // it could be a reply to a peer or a local client
                    // [WORKER_READY] or [client adr][empty][data] or [peer adr][empty][peer client adr][empty][data]
                    if (msg[0].Buffer[0] != WorkerReady)
                    {
                        Debug.Assert(msg.FrameCount > 2, "[LocalBackend] None READY message malformed");

                        // if the adr (first frame) is any of the clients send the REPLY there
                        // and send it to the peer otherwise
                        if (clients.Any(n => AreSame(n, msg.First)))
                            localFrontend.SendMessage(msg);
                        else
                            cloudFrontend.SendMessage(msg);
                    }
                };

                // this socket is connected to all peers
                // we receive either a REQ or a REPLY form a peer
                // REQ [peer adr][empty][peer client adr][empty][message id] -> send to peer for processing
                // REP [peer adr][empty][client adr][empty][message id] -> send to local client
                cloudBackend.ReceiveReady += (s, e) =>
                {
                    var msg = e.Socket.ReceiveMultipartMessage();

                    // just to make sure we received a message
                    Debug.Assert(msg != null && msg.FrameCount > 0, "[CloudBackend] message was empty or frame count == 0!");

                    // we need the peers address for proper addressing
                    var peerAdr = Unwrap(msg);

                    // the remaining message must be at least 3 frames!
                    Debug.Assert(msg.FrameCount > 2, "[CloudBackend] message malformed");

                    // if the id is any of the local clients it is a REPLY
                    // and a REQ otherwise
                    if (clients.Any(n => AreSame(n, msg.First)))
                    {
                        // [client adr][empty][message id]
                        localFrontend.SendMessage(msg);
                    }
                    else
                    {
                        // add the peers address to the request
                        var request = Wrap(peerAdr, msg);
                        // [peer adr][empty][peer client adr][empty][message id]
                        cloudFrontend.SendMessage(request);
                    }
                };

                // all peers are binding to this socket
                // we receive REPLY or REQ from peers
                // REQ [peer adr][empty][peer client adr][empty][data] -> send to local worker for processing
                // REP [peer adr][empty][client adr][empty][data] -> send to local client
                cloudFrontend.ReceiveReady += (s, e) =>
                {
                    var msg = e.Socket.ReceiveMultipartMessage();

                    // just to make sure we received a message
                    Debug.Assert(msg != null && msg.FrameCount > 0, "[CloudFrontend] message was empty or frame count == 0!");

                    // we may need need the peers address for proper addressing
                    var peerAdr = Unwrap(msg);

                    // the remaining message must be at least 3 frames!
                    Debug.Assert(msg.FrameCount > 2, "[CloudFrontend] message malformed");

                    // if the address is any of the local clients it is a REPLY
                    // and a REQ otherwise
                    if (clients.Any(n => AreSame(n, msg.First)))
                        localFrontend.SendMessage(msg);
                    else
                    {
                        // in order to know which per to send back the peers adr must be added again
                        var original = Wrap(peerAdr, msg);

                        // reduce the capacity to reflect the use of a worker by a cloud request
                        previousLocalCapacity = workerQueue.Count;
                        // get the LRU worker
                        var workerAdr = workerQueue.Dequeue();
                        // wrap the message with the worker address and send
                        var request = Wrap(workerAdr, original);
                        localBackend.SendMessage(request);
                    }
                };

                // in order to reduce chatter we only check to see if we have local capacity to provide to cloud
                // periodically every 2 seconds with a timer
                var timer = new NetMQTimer((int)TimeSpan.FromSeconds(2).TotalMilliseconds);

                timer.Elapsed += (t, e) =>
                {
                    // send message only if the previous send information changed
                    if (previousLocalCapacity != workerQueue.Count)
                    {
                        // set the information
                        previousLocalCapacity = workerQueue.Count;
                        // generate the message
                        var msg = new NetMQMessage();
                        var data = new NetMQFrame(previousLocalCapacity.ToString());
                        msg.Append(data);
                        var stateMessage = Wrap(Encoding.UTF8.GetBytes(me), msg);
                        // publish info
                        stateBackend.SendMessage(stateMessage);
                    }

                    // restart the timer
                    e.Timer.Enable = true;
                };

                // start all clients and workers as threads
                var clientTasks = new Thread[NbrClients];
                var workerTasks = new Thread[NbrWorker];

                for (var i = 0; i < NbrClients; i++)
                {
                    var client = new Client(localFrontendAddress, monitorAddress, (byte)i);
                    clientTasks[i] = new Thread(client.Run) { Name = string.Format("Client_{0}", i) };
                    clientTasks[i].Start();
                }

                for (var i = 0; i < NbrWorker; i++)
                {
                    var worker = new Worker(localBackendAddress, (byte)i);
                    workerTasks[i] = new Thread(worker.Run) { Name = string.Format("Worker_{0}", i) };
                    workerTasks[i].Start();
                }

                var sockets = new NetMQSocket[]
                {
                    localFrontend,
                    localBackend,
                    cloudFrontend,
                    cloudBackend,
                    stateFrontend,
                    stateBackend,
                    monitor
                };

                // create poller and add sockets & timer
                var poller = new Poller(sockets);

                poller.AddTimer(timer);

                // start monitoring the sockets
                Task.Factory.StartNew(poller.PollTillCancelled);

                // we wait for a CTRL+C to exit
                while (s_keepRunning)
                {}

                Console.WriteLine("Ctrl-C encountered! Exiting the program!");

                if (poller.IsStarted)
                    poller.CancelAndJoin();

                poller.Dispose();
            }
        }
예제 #15
0
        /// <summary>
        /// Start proxying messages between the front and back ends.
        /// </summary>
        /// <exception cref="InvalidOperationException">The proxy has already been started.</exception>
        public void Start()
        {
            _status = "Attempting to start";
            if (Interlocked.CompareExchange(ref _state, Running, NotStarted) != NotStarted)
            {
                throw new InvalidOperationException("ZeroMQ XPub-XSub hub has already been started");
            }
            _status = "Starting";

            _subscriber.ReceiveReady += OnSubscriberReady;
            _publisher.ReceiveReady += OnPublisherReady;

            _poller = new Poller(_subscriber, _publisher);
            if (_heartbeat != null)
            {
                _poller.AddTimer(_heartbeat);
            }

            this.SetJobState(JobState.Running);
            _status = "Started";
            _poller.PollTillCancelledNonBlocking();
            _status = "Running Until Canceled";
        }
예제 #16
0
        private SubscriberSocket Connect(string[] addresses)
        {
            List<SubscriberSocket> sockets = new List<SubscriberSocket>();
              Poller poller = new Poller();

              SubscriberSocket connectedSocket = null;

              // event handler to handle message from socket
              EventHandler<NetMQSocketEventArgs> handleMessage = (sender, args) =>
              {
            if (connectedSocket == null)
            {
              connectedSocket = (SubscriberSocket) args.Socket;
              poller.Cancel();
            }
              };

              // If timeout elapsed just cancel the poller without seting the connected socket
              NetMQTimer timeoutTimer = new NetMQTimer(TimeSpan.FromSeconds(5));
              timeoutTimer.Elapsed += (sender, args) => poller.Cancel();
              poller.AddTimer(timeoutTimer);

              foreach (var address in addresses)
              {
            var socket = m_context.CreateSubscriberSocket();
            sockets.Add(socket);

            socket.ReceiveReady += handleMessage;
            poller.AddSocket(socket);

            // Subscribe to welcome message
            socket.Subscribe("WM");
            socket.Connect(address);
              }

              poller.PollTillCancelled();

              // if we a connected socket the connection attempt succeed
              if (connectedSocket != null)
              {
            // remove the connected socket form the list
            sockets.Remove(connectedSocket);

            // close all existing sockets
            CloseSockets(sockets);

            // drop the welcome message
            connectedSocket.SkipMultipartMessage();

            // subscribe to heartbeat
            connectedSocket.Subscribe("HB");

            // subscribe to our only topic
            connectedSocket.Subscribe("A");

            connectedSocket.ReceiveReady -= handleMessage;
            connectedSocket.ReceiveReady += OnSubscriberMessage;

            return connectedSocket;
              }
              else
              {
            // close all existing sockets
            CloseSockets(sockets);

            return null;
              }
        }
예제 #17
0
파일: Client.cs 프로젝트: wangkai2014/netmq
        public void Run()
        {
            Console.WriteLine("[CLIENT {0}] Starting", m_id);

            var rnd = new Random(m_id);
            // each request shall have an unique id in order to recognize an reply for a request
            var messageId = new byte[5];
            // create clientId for messages
            var clientId = new[] { m_id };
            // a flag to signal that an answer has arrived
            bool messageAnswered = false;
            // we use a poller because we have a socket and a timer to monitor
            using (var clientPoller = new Poller())
            using (var context = NetMQContext.Create())
            using (var client = context.CreateRequestSocket())
            using (var monitor = context.CreatePushSocket())
            {
                client.Connect(m_localFrontendAddress);
                monitor.Connect(m_monitorAddress);

                client.Options.Identity = new[] { m_id };
                var timer = new NetMQTimer((int)TimeSpan.FromSeconds(10).TotalMilliseconds);

                // use as flag to indicate exit
                var exit = false;

                // every 10 s check if message has been received, if not then send error message and ext
                // and restart timer otherwise
                timer.Elapsed += (s, e) =>
                {
                    if (messageAnswered)
                    {
                        e.Timer.Enable = true;
                    }
                    else
                    {
                        var msg = string.Format("[CLIENT {0}] ERR - EXIT - lost message {1}", m_id, messageId);
                        // send an error message
                        monitor.Send(msg);

                        // if poller is started than stop it
                        if (clientPoller.IsStarted)
                            clientPoller.CancelAndJoin();
                        // mark the required exit
                        exit = true;
                    }
                };

                // process arriving answers
                client.ReceiveReady += (s, e) =>
                {
                    // mark the arrival of an answer
                    messageAnswered = true;
                    // worker is supposed to answer with our request id
                    var reply = e.Socket.ReceiveMultipartMessage();

                    if (reply.FrameCount == 0)
                    {
                        // something went wrong
                        monitor.Send(string.Format("[CLIENT {0}] Received an empty message!", m_id));
                        // mark the exit flag to ensure the exit
                        exit = true;
                    }
                    else
                    {
                        var sb = new StringBuilder();

                        // create success message
                        foreach (var frame in reply)
                            sb.Append("[" + frame.ConvertToString() + "]");

                        // send the success message
                        monitor.Send(string.Format("[CLIENT {0}] Received answer {1}",
                            m_id,
                            sb.ToString()));
                    }
                };

                // add socket & timer to poller
                clientPoller.AddSocket(client);
                clientPoller.AddTimer(timer);

                // start poller in another thread to allow the continued processing
                clientPoller.PollTillCancelledNonBlocking();

                // if true the message has been answered
                // the 0th message is always answered
                messageAnswered = true;

                while (!exit)
                {
                    // simulate sporadic activity by randomly delaying
                    Thread.Sleep((int)TimeSpan.FromSeconds(rnd.Next(5)).TotalMilliseconds);

                    // only send next message if the previous one has been replied to
                    if (messageAnswered)
                    {
                        // generate random 5 byte as identity for for the message
                        rnd.NextBytes(messageId);

                        messageAnswered = false;

                        // create message [client adr][empty][message id] and send it
                        var msg = new NetMQMessage();

                        msg.Push(messageId);
                        msg.Push(NetMQFrame.Empty);
                        msg.Push(clientId);

                        client.SendMessage(msg);
                    }
                }

                // stop poller if needed
                if (clientPoller.IsStarted)
                    clientPoller.CancelAndJoin();
            }
        }
예제 #18
0
        private void Run(PairSocket shim)
        {
            using (m_publisherSocket = m_context.CreateXPublisherSocket())
            {
                m_publisherSocket.SetWelcomeMessage(WelcomeMessage);
                m_publisherSocket.Bind(m_address);

                m_publisherSocket.ReceiveReady += DropPublisherSubscriptions;

                m_heartbeatTimer = new NetMQTimer(HeartbeatInterval);
                m_heartbeatTimer.Elapsed += OnHeartbeatTimerElapsed;

                shim.ReceiveReady += OnShimMessage;

                // signal the actor that the shim is ready to work
                shim.SignalOK();

                m_poller = new Poller(m_publisherSocket, shim);
                m_poller.AddTimer(m_heartbeatTimer);

                // Polling until poller is cancelled
                m_poller.PollTillCancelled();
            }
        }