/// <summary>
        /// Start monitor the socket, the method doesn't start a new thread and will block until the monitor poll is stopped
        /// </summary>
        /// <exception cref="InvalidOperationException">The Monitor must not have already started nor attached to a poller.</exception>
        public void Start()
        {
            // in case the sockets is created in another thread
            Thread.MemoryBarrier();

            if (IsRunning)
            {
                throw new InvalidOperationException("Monitor already started");
            }

            if (m_attachedPoller != null)
            {
                throw new InvalidOperationException("Monitor attached to a poller");
            }

            try
            {
                InternalStart();

                while (m_cancel == 0)
                {
                    m_monitoringSocket.Poll(Timeout);
                }
            }
            finally
            {
                InternalClose();
            }
        }
Пример #2
0
        /// <summary>
        ///     send a request to a broker for a specific service and receive the reply
        ///
        ///     if the reply is not available within a specified time
        ///     the client deems the connection as lost and reconnects
        ///     for a specified number of times. if no reply is available
        ///     throughout this procedure the client abandons
        ///     the reply is checked for validity and returns the reply
        ///     according to the verbose flag it reports about its activities
        /// </summary>
        /// <param name="serviceName">the name of the service requested</param>
        /// <param name="request">the request message to process by service</param>
        /// <returns>the reply from service</returns>
        /// <exception cref="ApplicationException">malformed message received</exception>
        /// <exception cref="ApplicationException">malformed header received</exception>
        /// <exception cref="ApplicationException">reply received from wrong service</exception>
        public NetMQMessage Send(string serviceName, NetMQMessage request)
        {
            if (string.IsNullOrWhiteSpace(serviceName))
            {
                throw new ApplicationException("serviceName must not be empty or null.");
            }

            if (ReferenceEquals(request, null))
            {
                throw new ApplicationException("the request must not be null");
            }
            // memorize it for the event handler
            m_serviceName = serviceName;

            // if for any reason the socket is NOT connected -> connect it!
            if (!m_connected)
            {
                Connect();
            }

            var message = new NetMQMessage(request);

            // prefix the request according to MDP specs
            // Frame 1: "MDPCxy" (six bytes MDP/Client x.y)
            // Frame 2: service name as printable string
            // Frame 3: request
            message.Push(serviceName);
            message.Push(m_mdpClient);

            Log(string.Format("[CLIENT INFO] sending {0} to service {1}", message, serviceName));

            var retiesLeft = Retries;

            while (retiesLeft > 0)
            {
                // beware of an exception if broker has not picked up the message at all
                // because one can not send multiple times! it is strict REQ -> REP -> REQ ...
                m_client.SendMultipartMessage(message);

                // Poll -> see ReceiveReady for event handling
                if (m_client.Poll(Timeout))
                {
                    // set by event handler
                    return(m_reply);
                }
                // if it failed assume communication dead and re-connect
                if (--retiesLeft > 0)
                {
                    Log("[CLIENT WARNING] no reply, reconnecting ...");

                    Connect();
                }
            }

            Log("[CLIENT ERROR] permanent error, abandoning!");

            m_client.Dispose();

            return(null);
        }
Пример #3
0
        // on message pushed to me.
        private void OnPull()
        {
            while (!this.token_pp.IsCancellationRequested)
            {
                puller.Poll(TimeSpan.FromMilliseconds(100));
                //try
                //{
                //    while (hasMore)
                //    {
                //        sb.Append(Encoding.UTF8.GetString(this.puller.Receive(SendReceiveOptions.DontWait, out hasMore)));
                //    }

                //    string msg = sb.ToString();
                //    sb.Clear();
                //    if (msg.Length > 0)
                //    {
                //        pullMsgHandler(msg);
                //    }
                //}
                //catch (Exception ce)
                //{
                //    Console.WriteLine("OnPull Error: {0}", ce.Message);
                //    log.Error("Pulling Message error: ", ce);
                //}
            }
            log.Debug("Puller Closed");
            puller.Close();
        }
Пример #4
0
 /// <summary>
 ///
 /// </summary>
 public void Start()
 {
     m_server = new RouterSocket();
     m_server.Bind("tcp://*:" + ListnenPort);
     m_server.ReceiveReady += Server_ReceiveReady;
     m_server.SendReady    += Server_SendReady;
     m_started              = true;
     new Thread(() =>
     {
         long nextSend = 0, nextHeartBeat = 0;
         while (m_started)
         {
             var tmp = TimeSpan.FromMilliseconds(1);
             m_server.Poll(tmp);
             if (nextSend <= 0)
             {
                 SendQueue();
                 nextSend = SendInterval;
             }
             if (nextHeartBeat <= 0)
             {
                 Heartbeat();
                 nextHeartBeat = PingInterval;
             }
             nextSend      -= 10;
             nextHeartBeat -= 10;
             Thread.Sleep(10);
         }
     })
     {
         IsBackground = true
     }.Start();
 }
Пример #5
0
        /// <summary>
        /// Start monitor the socket, the method doesn't start a new thread and will block until the monitor poll is stopped
        /// </summary>
        /// <exception cref="InvalidOperationException">The Monitor must not have already started nor attached to a poller.</exception>
        public void Start()
        {
            if (IsRunning)
            {
                throw new InvalidOperationException("Monitor already started");
            }

            if (m_attachedPoller != null)
            {
                throw new InvalidOperationException("Monitor attached to a poller");
            }

            try
            {
                InternalStart();

                while (m_cancel == 0)
                {
                    m_monitoringSocket.Poll(Timeout);
                }
            }
            finally
            {
                InternalClose();
            }
        }
Пример #6
0
            /// <summary>
            /// Listens the specified on message received.
            /// </summary>
            /// <param name="onMessageReceived">The on message received.</param>
            /// <param name="token">The tokenSource.</param>
            internal void Listen(Action <Message> onMessageReceived, CancellationTokenSource token)
            {
                socket.ReceiveReady += (sender, args) =>
                {
                    var inbound = socket.ReceiveString();

                    var message = Message.FromJson(inbound);
                    onMessageReceived(message);
                };

                while (!token.IsCancellationRequested)
                {
                    socket.Poll();
                }
            }
Пример #7
0
        public string Request(string service, string msg, int timeoutmsec)
        {
            string      resp    = string.Empty;
            LinkAddress address = config.ReqRep.FindLinkAddress(service);

            if (address == null)
            {
                return(resp);
            }

            bool   pollResult = false;
            string requestId  = Guid.NewGuid().ToString();

            using (NetMQContext context = NetMQContext.Create())
            {
                NetMQSocket client = context.CreateRequestSocket();
                client.Options.Linger   = TimeSpan.Zero;
                client.Options.Identity = Encoding.UTF8.GetBytes(requestId);
                client.Connect(address.Address);
                try
                {
                    byte[] data = Encoding.UTF8.GetBytes(msg);
                    client.Send(data);
                }
                catch (Exception)
                {
                    client.Disconnect(address.Address);
                    client.Dispose();
                    return(resp);
                }

                client.ReceiveReady += ClientOnReceiveReady;
                pollResult           = client.Poll(TimeSpan.FromMilliseconds(timeoutmsec));
                client.ReceiveReady -= ClientOnReceiveReady;
                client.Disconnect(address.Address);
                client.Dispose();
            }

            if (pollResult)
            {
                if (responseMsgs.ContainsKey(requestId))
                {
                    responseMsgs.TryRemove(requestId, out resp);
                }
            }

            return(resp);
        }
Пример #8
0
        private static bool TryRequest(NetMQContext context, string endpoint, string requestString)
        {
            Console.WriteLine("Trying echo service at {0}", endpoint);
            NetMQSocket client = context.CreateRequestSocket();

            client.Options.Linger = TimeSpan.Zero;
            client.Connect(endpoint);
            client.Send(requestString);
            client.ReceiveReady += ClientOnReceiveReady;
            bool pollResult = client.Poll(TimeSpan.FromMilliseconds(REQUEST_TIMEOUT));

            client.ReceiveReady -= ClientOnReceiveReady;
            client.Disconnect(endpoint);
            client.Dispose();

            return(pollResult);
        }
Пример #9
0
        static void Main(string[] args)
        {
            using (var context = NetMQContext.Create())
            {
                worker = context.CreateRequestSocket();

                var randomizer = new Random(DateTime.Now.Millisecond);
                Guid guid = Guid.NewGuid();
                worker.Options.Identity = Encoding.Unicode.GetBytes(guid.ToString());
                worker.ReceiveReady += WorkerOnReceiveReady;
                worker.Connect(SERVER_ENDPOINT);

                Console.WriteLine("W: {0} worker ready", guid);
                worker.Send(Encoding.Unicode.GetBytes(LRU_READY));

                var cycles = 0;
                while (true)
                {
                    cycles += 1;
                    if (cycles > 3 && randomizer.Next(0, 5) == 0)
                    {
                        Console.WriteLine("W: {0} simulating a crash", guid);
                        System.Threading.Thread.Sleep(5000);
                        //break;
                    }
                    else if (cycles > 3 && randomizer.Next(0, 5) == 0)
                    {
                        Console.WriteLine("W: {0} simulating CPU overload", guid);
                        System.Threading.Thread.Sleep(3000);
                    }
                    Console.WriteLine("W: {0} normal reply", guid);

                    worker.Poll(TimeSpan.FromMilliseconds(1000));
                }

            }
        }
Пример #10
0
        static void Main(string[] args)
        {
            using (var context = NetMQContext.Create())
            {
                worker = context.CreateRequestSocket();

                var  randomizer = new Random(DateTime.Now.Millisecond);
                Guid guid       = Guid.NewGuid();
                worker.Options.Identity = Encoding.Unicode.GetBytes(guid.ToString());
                worker.ReceiveReady    += WorkerOnReceiveReady;
                worker.Connect(SERVER_ENDPOINT);

                Console.WriteLine("W: {0} worker ready", guid);
                worker.Send(Encoding.Unicode.GetBytes(LRU_READY));

                var cycles = 0;
                while (true)
                {
                    cycles += 1;
                    if (cycles > 3 && randomizer.Next(0, 5) == 0)
                    {
                        Console.WriteLine("W: {0} simulating a crash", guid);
                        System.Threading.Thread.Sleep(5000);
                        //break;
                    }
                    else if (cycles > 3 && randomizer.Next(0, 5) == 0)
                    {
                        Console.WriteLine("W: {0} simulating CPU overload", guid);
                        System.Threading.Thread.Sleep(3000);
                    }
                    Console.WriteLine("W: {0} normal reply", guid);

                    worker.Poll(TimeSpan.FromMilliseconds(1000));
                }
            }
        }
Пример #11
0
        /// <summary>
        ///     initially sends a READY message to the broker upon connection
        ///     and waits for a request to come
        /// </summary>
        /// <param name="reply">the reply to send</param>
        /// <returns>the request to process</returns>
        /// <remarks>
        ///     if it is the initial call to Receive - reply must be <c>null</c> in order to
        ///     send READY and subsequently wait for a request.
        ///     reply == <c>null</c> will bypass the sending of a message!
        /// </remarks>
        public NetMQMessage Receive(NetMQMessage reply)
        {
            // set the number of left retries to connect
            m_retriesLeft = m_connectionRetries;

            if (!m_connected)
            {
                Connect();
            }

            // since Connect send the READY we are waiting after a Connect for a
            // REQ and must skip the REPLY step
            // if however the Connect has not been called than we have received
            // and processed a REQ and must send a REP and at one must be pending
            if (!ReferenceEquals(reply, null) && m_expectReply != 0)
            {
                if (ReferenceEquals(m_returnIdentity, null) || m_returnIdentity.BufferSize == 0)
                {
                    throw new ApplicationException("A malformed reply has been provided");
                }

                var message = Wrap(reply, m_returnIdentity);        // [client id][e][reply]

                Send(MDPCommand.Reply, null, message);
            }

            m_expectReply = 1;
            // now wait for the next request
            while (!m_exit)
            {
                // see ReceiveReady event handler -> ProcessReceiveReady
                if (m_worker.Poll(HeartbeatDelay))
                {
                    // a request has been received, so connection is established - reset the connection retries
                    m_retriesLeft = m_connectionRetries;
                    // ProcessReceiveReady will set m_request only if a request arrived
                    if (!ReferenceEquals(m_request, null))
                    {
                        return(m_request);
                    }
                }
                else
                {
                    // if m_liveliness times no message has been received -> try to reconnect
                    if (--m_liveliness == 0)
                    {
                        // if we tried it _HEARTBEAT_LIVELINESS * m_connectionRetries times without
                        // success therefor we deem the broker dead or the communication broken
                        // and abandon the worker
                        if (--m_retriesLeft < 0)
                        {
                            Log("[WORKER] abandoning worker due to errors!");
                            break;
                        }

                        Log("[WORKER INFO] disconnected from broker - retrying ...");

                        // wait before reconnecting
                        Thread.Sleep(HeartbeatDelay);
                        // reconnect
                        Connect();
                    }

                    Send(MDPCommand.Heartbeat, null, null);
                    // set new point in time for sending the next heartbeat
                }
            }

            if (m_exit)
            {
                Log("[WORKER] abandoning worker due to request!");
            }

            m_worker.Dispose();

            return(null);
        }
Пример #12
0
        private void ReceiveEvents(String subscriptionUri, String topic, CancellationToken cancellationToken)
        {
            using (NetMQContext context = NetMQContext.Create())
            {
                using (NetMQSocket subscriberSocket = context.CreateSubscriberSocket())
                {
                    subscriberSocket.IgnoreErrors = true;
                    subscriberSocket.Connect(subscriptionUri);
                    subscriberSocket.Subscribe(topic);

                    Logger.Info("ZeroMQCache: Connected to subscriptionUri \"{0}\".", subscriptionUri);

                    // Eventhandler delegate to handle receiving messages
                    subscriberSocket.ReceiveReady += (sender, args) =>
                    {
                        try
                        {
                            if (args.ReceiveReady)
                            {
                                // Recieve and relay
                                NetMQMessage netMQmessage = args.Socket.ReceiveMessage();

                                // Recieve the message
                                ZeroMQMessage message = new ZeroMQMessage()
                                {
                                    Topic   = netMQmessage.Pop().ConvertToString(),
                                    Client  = netMQmessage.Pop().ConvertToString(),
                                    Content = netMQmessage.Pop().ConvertToString()
                                };

                                Logger.Debug("ZeroMQCache: Received -> {0}", message.ToString());

                                XmlCacheEvent cacheEvent = XmlCacheEvent.FromXml(message.Content);

                                if (cacheEvent != null)
                                {
                                    OnCacheEvent(cacheEvent.CacheRegion, cacheEvent.Key, cacheEvent.EventType);
                                }
                            }
                        }
                        catch (OperationCanceledException)
                        {
                            // We have been asked to cancel operation
                            return;
                        }
                        catch (Exception ex)
                        {
                            Logger.Error("ZeroMQCache: Error receiving message.", ex);
                        }
                    };

                    while (!cancellationToken.IsCancellationRequested)
                    {
                        try
                        {
                            subscriberSocket.Poll(TimeSpan.FromSeconds(1));
                        }
                        catch (OperationCanceledException)
                        {
                            // We have been asked to cancel operation
                            break;
                        }
                        catch (Exception ex)
                        {
                            Logger.Error("ZeroMQCache: Error polling for messages.", ex);
                        }
                    }

                    // Close socket
                    subscriberSocket.Close();
                }

                context.Terminate();
            }
        }
        private void ReceiveEvents(String submissionUri, String topic, CancellationToken cancellationToken)
        {
            using (NetMQContext context = NetMQContext.Create())
            {
                using (NetMQSocket pullSocket = context.CreatePullSocket())
                {
                    pullSocket.IgnoreErrors = true;
                    pullSocket.Bind(submissionUri);

                    Logger.Info("ZeroMQBroker: Bound to submissionUri \"{0}\".", submissionUri);

                    // Eventhandler delegate to handle receiving messages
                    pullSocket.ReceiveReady += (sender, args) =>
                    {
                        try
                        {
                            if (args.ReceiveReady)
                            {
                                // Recieve and relay
                                NetMQMessage netMQmessage = args.Socket.ReceiveMessage();

                                // Recieve the message
                                ZeroMQMessage message = new ZeroMQMessage()
                                {
                                    Topic   = netMQmessage.Pop().ConvertToString(),
                                    Client  = netMQmessage.Pop().ConvertToString(),
                                    Content = netMQmessage.Pop().ConvertToString()
                                };

                                Logger.Debug("ZeroMQBroker: Received -> {0}", message.ToString());

                                mQueue.Add(message);

                                // ZeroMQBroker relays multiple topics, verify if the message was meant for the current client
                                if (String.Equals(topic, message.Topic, StringComparison.OrdinalIgnoreCase))
                                {
                                    XmlCacheEvent cacheEvent = XmlCacheEvent.FromXml(message.Content);

                                    if (cacheEvent != null)
                                    {
                                        OnCacheEvent(cacheEvent.CacheRegion, cacheEvent.Key, cacheEvent.EventType);
                                    }
                                }
                            }
                        }
                        catch (OperationCanceledException)
                        {
                            // We have been asked to cancel operation
                            return;
                        }
                        catch (Exception ex)
                        {
                            Logger.Error("ZeroMQBroker: Error receiving message.", ex);
                        }
                    };

                    while (!cancellationToken.IsCancellationRequested)
                    {
                        try
                        {
                            pullSocket.Poll(TimeSpan.FromSeconds(1));
                        }
                        catch (OperationCanceledException)
                        {
                            // We have been asked to cancel operation
                            break;
                        }
                        catch (Exception ex)
                        {
                            Logger.Error("ZeroMQBroker: Error polling for messages.", ex);
                        }
                    }

                    // Close socket
                    pullSocket.Close();
                }

                context.Terminate();
            }
        }