Пример #1
0
        static int Main(string[] args)
        {
            if (args.Length != 3)
            {
                Console.WriteLine("usage: remote_lat remote_lat <connect-to> <message-size> <roundtrip-count>");
                return 1;
            }

            string connectTo = args[0];
            int messageSize = int.Parse(args[1]);
            int roundtripCount = int.Parse(args[2]);

            var context = ZMQ.CtxNew();
            var reqSocket = ZMQ.Socket(context, ZmqSocketType.Req);
            bool connected = reqSocket.Connect(connectTo);
            if (!connected)
            {
                Console.WriteLine("error in zmq_connect");
            }

            var message = new Msg(messageSize);

            var stopWatch = Stopwatch.StartNew();

            for (int i = 0; i != roundtripCount; i++)
            {
                bool sent = reqSocket.Send(message, SendRecieveOptions.None);
                if (!sent)
                {
                    Console.WriteLine("error in zmq_sendmsg");
                    return -1;
                }

                message = reqSocket.Recv(SendRecieveOptions.None);
                if (message.Size != messageSize)
                {
                    Console.WriteLine("message of incorrect size received. Received: " + message.Size + " Expected: " + messageSize);
                    return -1;
                }
            }

            stopWatch.Stop();

            message.Close();

            double elapsedMicroseconds = stopWatch.ElapsedTicks * 1000000 / Stopwatch.Frequency;
            double latency = elapsedMicroseconds / (roundtripCount * 2);

            Console.WriteLine("message size: {0} [B]", messageSize);
            Console.WriteLine("roundtrip count: {0}", roundtripCount);
            Console.WriteLine("average latency: {0:0.000} [µs]", latency);

            reqSocket.Close();
            context.Terminate();

            return 0;
        }
Пример #2
0
        public void Plug(IOThread ioThread, SessionBase session)
        {
            m_encoder.SetMsgSource(session);

            AddFd(m_socket);
            SetPollout(m_socket);

            // get the first message from the session because we don't want to send identities

            Msg msg = new Msg();

            msg.InitEmpty();

            bool ok = session.PullMsg(ref msg);

            if (ok)
            {
                msg.Close();
            }
        }
Пример #3
0
        //  Remove any half processed messages. Flush unflushed messages.
        //  Call this function when engine disconnect to get rid of leftovers.
        private void CleanPipes()
        {
            if (m_pipe != null)
            {
                //  Get rid of half-processed messages in the out pipe. Flush any
                //  unflushed messages upstream.
                m_pipe.Rollback();
                m_pipe.Flush();

                //  Remove any half-read message from the in pipe.
                while (m_incompleteIn)
                {
                    Msg msg = PullMsg();
                    if (msg == null)
                    {
                        Debug.Assert(!m_incompleteIn);
                        break;
                    }
                    msg.Close();
                }
            }
        }
Пример #4
0
        static XSub()
        {
            s_sendSubscription = (data, size, arg) => {

                                                       	Pipe pipe = (Pipe) arg;

                                                       	//  Create the subsctription message.
                                                       	Msg msg = new Msg(size + 1);
                                                       	msg.Put((byte)1);
                                                       	msg.Put(data,1, size);

                                                       	//  Send it to the pipe.
                                                       	bool sent = pipe.Write (msg);
                                                       	//  If we reached the SNDHWM, and thus cannot send the subscription, drop
                                                       	//  the subscription message instead. This matches the behaviour of
                                                       	//  zmq_setsockopt(ZMQ_SUBSCRIBE, ...), which also drops subscriptions
                                                       	//  when the SNDHWM is reached.
                                                       	if (!sent)
                                                       		msg.Close ();

            };
        }
Пример #5
0
        static XSub()
        {
            s_sendSubscription = (data, size, arg) => {
                Pipe pipe = (Pipe)arg;

                //  Create the subsctription message.
                Msg msg = new Msg(size + 1);
                msg.Put((byte)1);
                msg.Put(data, 1, size);

                //  Send it to the pipe.
                bool sent = pipe.Write(msg);
                //  If we reached the SNDHWM, and thus cannot send the subscription, drop
                //  the subscription message instead. This matches the behaviour of
                //  zmq_setsockopt(ZMQ_SUBSCRIBE, ...), which also drops subscriptions
                //  when the SNDHWM is reached.
                if (!sent)
                {
                    msg.Close();
                }
            };
        }
Пример #6
0
        protected override void ProcessPipeTermAck()
        {
            //  Notify the user that all the references to the pipe should be dropped.
            Debug.Assert(m_sink != null);
            m_sink.Terminated(this);

            //  In terminating and double_terminated states there's nothing to do.
            //  Simply deallocate the pipe. In terminated state we have to ack the
            //  peer before deallocating this side of the pipe. All the other states
            //  are invalid.
            if (m_state == State.Terminated)
            {
                m_outboundPipe = null;
                SendPipeTermAck(m_peer);
            }
            else
            {
                Debug.Assert(m_state == State.Terminating || m_state == State.DoubleTerminated);
            }

            //  We'll deallocate the inbound pipe, the peer will deallocate the outbound
            //  pipe (which is an inbound pipe from its point of view).
            //  First, delete all the unread messages in the pipe. We have to do it by
            //  hand because msg_t doesn't have automatic destructor. Then deallocate
            //  the ypipe itself.
            var msg = new Msg();

            if (m_inboundPipe != null)
            {
                while (m_inboundPipe.Read(ref msg))
                {
                    msg.Close();
                }
            }

            m_inboundPipe = null;
        }
Пример #7
0
        protected override void XReadActivated(Pipe pipe)
        {
            //  There are some subscriptions waiting. Let's process them.
            Msg sub = new Msg();

            while (pipe.Read(ref sub))
            {
                //  Apply the subscription to the trie.
                byte[] data = sub.Data;
                int    size = sub.Size;
                if (size > 0 && (data[0] == 0 || data[0] == 1))
                {
                    bool unique;
                    if (data[0] == 0)
                    {
                        unique = m_subscriptions.Remove(data, 1, size - 1, pipe);
                    }
                    else
                    {
                        unique = m_subscriptions.Add(data, 1, size - 1, pipe);
                    }

                    //  If the subscription is not a duplicate, store it so that it can be
                    //  passed to used on next recv call.
                    if (m_options.SocketType == ZmqSocketType.Xpub && (unique || m_verbose))
                    {
                        m_pending.Enqueue(new Blob(sub.Data, sub.Size));
                    }
                }
                else // process message unrelated to sub/unsub
                {
                    m_pending.Enqueue(new Blob(sub.Data, sub.Size));
                }

                sub.Close();
            }
        }
Пример #8
0
        protected override void ProcessHiccup(object pipe)
        {
            //  Destroy old out-pipe. Note that the read end of the pipe was already
            //  migrated to this thread.
            Debug.Assert(m_outboundPipe != null);
            m_outboundPipe.Flush();
            var msg = new Msg();

            while (m_outboundPipe.Read(ref msg))
            {
                msg.Close();
            }

            //  Plug in the new out-pipe.
            Debug.Assert(pipe != null);
            m_outboundPipe = (YPipe <Msg>)pipe;
            m_outActive    = true;

            //  If appropriate, notify the user about the hiccup.
            if (m_state == State.Active)
            {
                m_sink.Hiccuped(this);
            }
        }
Пример #9
0
        public virtual void PushMsg(ref Msg msg)
        {
            //  First message to receive is identity (if required).
            if (!m_identityReceived)
            {
                msg.SetFlags(MsgFlags.Identity);
                m_identityReceived = true;

                if (!m_options.RecvIdentity)
                {
                    msg.Close();
                    msg.InitEmpty();
                    return;
                }
            }

            if (m_pipe != null && m_pipe.Write(ref msg))
            {
                msg.InitEmpty();
                return;
            }

            throw AgainException.Create();
        }
Пример #10
0
        public virtual bool PushMsg(ref Msg msg)
        {
            //  First message to receive is identity (if required).
            if (!m_identityReceived)
            {
                msg.SetFlags(MsgFlags.Identity);
                m_identityReceived = true;

                if (!m_options.RecvIdentity)
                {
                    msg.Close();
                    msg.InitEmpty();
                    return(true);
                }
            }

            if (m_pipe != null && m_pipe.Write(ref msg))
            {
                msg.InitEmpty();
                return(true);
            }

            return(false);
        }
Пример #11
0
        protected override void ProcessHiccup(object pipe)
        {
            //  Destroy old out-pipe. Note that the read end of the pipe was already
            //  migrated to this thread.
            Debug.Assert(m_outboundPipe != null);
            m_outboundPipe.Flush();
            var msg = new Msg();
            while (m_outboundPipe.Read(out msg))
            {
                msg.Close();
            }

            //  Plug in the new out-pipe.
            Debug.Assert(pipe != null);
            m_outboundPipe = (YPipe<Msg>)pipe;
            m_outActive = true;

            //  If appropriate, notify the user about the hiccup.
            if (m_state == State.Active)
                m_sink.Hiccuped(this);
        }
Пример #12
0
        protected override bool XSend(ref Msg msg, SendReceiveOptions flags)
        {
            //  If this is the first part of the message it's the ID of the
            //  peer to send the message to.
            if (!m_moreOut)
            {
                Debug.Assert(m_currentOut == null);

                //  If we have malformed message (prefix with no subsequent message)
                //  then just silently ignore it.
                //  TODO: The connections should be killed instead.
                if (msg.HasMore)
                {
                    m_moreOut = true;

                    //  Find the pipe associated with the identity stored in the prefix.
                    //  If there's no such pipe just silently ignore the message, unless
                    //  mandatory is set.
                    Blob    identity = new Blob(msg.Data, msg.Size);
                    Outpipe op;

                    if (m_outpipes.TryGetValue(identity, out op))
                    {
                        m_currentOut = op.Pipe;
                        if (!m_currentOut.CheckWrite())
                        {
                            op.Active    = false;
                            m_currentOut = null;
                            if (m_mandatory)
                            {
                                m_moreOut = false;
                                return(false);
                            }
                        }
                    }
                    else if (m_mandatory)
                    {
                        m_moreOut = false;
                        throw NetMQException.Create(ErrorCode.EHOSTUNREACH);
                    }
                }

                //  Detach the message from the data buffer.
                msg.Close();
                msg.InitEmpty();

                return(true);
            }

            if (m_options.RawSocket)
            {
                msg.ResetFlags(MsgFlags.More);
            }

            //  Check whether this is the last part of the message.
            m_moreOut = msg.HasMore;

            //  Push the message into the pipe. If there's no out pipe, just drop it.
            if (m_currentOut != null)
            {
                // Close the remote connection if user has asked to do so
                // by sending zero length message.
                // Pending messages in the pipe will be dropped (on receiving term- ack)
                if (m_rawSocket && msg.Size == 0)
                {
                    m_currentOut.Terminate(false);
                    msg.Close();
                    msg.InitEmpty();
                    m_currentOut = null;
                    return(true);
                }

                bool ok = m_currentOut.Write(ref msg);
                if (!ok)
                {
                    m_currentOut = null;
                }
                else if (!m_moreOut)
                {
                    m_currentOut.Flush();
                    m_currentOut = null;
                }
            }
            else
            {
                msg.Close();
            }

            //  Detach the message from the data buffer.
            msg.InitEmpty();

            return(true);
        }
Пример #13
0
        public bool Send(Msg msg, SendRecieveOptions flags)
        {
            //  Drop the message if required. If we are at the end of the message
            //  switch back to non-dropping mode.
            if (m_dropping) {

                m_more = msg.HasMore;
                m_dropping = m_more;

                msg.Close ();
                return true;
            }

            while (m_active > 0) {
                if (m_pipes[m_current].Write (msg))
                    break;

                Debug.Assert(!m_more);
                m_active--;
                if (m_current < m_active)
                    Utils.Swap (m_pipes, m_current, m_active);
                else
                    m_current = 0;
            }

            //  If there are no pipes we cannot send the message.
            if (m_active == 0) {
                ZError.ErrorNumber = ErrorNumber.EAGAIN;
                return false;
            }

            //  If it's part of the message we can fluch it downstream and
            //  continue round-robinning (load balance).
            m_more = msg.HasMore;
            if (!m_more) {
                m_pipes[m_current].Flush();
                if (m_active > 1)
                    m_current = (m_current + 1) % m_active;
            }

            return true;
        }
Пример #14
0
        //  Remove any half processed messages. Flush unflushed messages.
        //  Call this function when engine disconnect to get rid of leftovers.
        private void CleanPipes()
        {
            if (m_pipe != null)
            {
                //  Get rid of half-processed messages in the out pipe. Flush any
                //  unflushed messages upstream.
                m_pipe.Rollback();
                m_pipe.Flush();

                //  Remove any half-read message from the in pipe.
                while (m_incompleteIn)
                {
                    var msg = new Msg();
                    msg.InitEmpty();

                    if (!PullMsg(ref msg))
                    {
                        Debug.Assert(!m_incompleteIn);
                        break;
                    }
                    msg.Close();
                }
            }
        }
Пример #15
0
        private bool IdentifyPeer(Pipe pipe)
        {
            Blob identity;

            if (m_options.RawSocket)
            {
                // Always assign identity for raw-socket
                byte[] buf = new byte[5];
                buf[0] = 0;
                byte[] result = BitConverter.GetBytes(m_nextPeerId++);
                Buffer.BlockCopy(result, 0, buf, 1, 4);
                identity = new Blob(buf, buf.Length);
            }
            else
            {
                //  Pick up handshake cases and also case where next identity is set

                Msg msg = new Msg();
                msg.InitEmpty();

                bool ok = pipe.Read(ref msg);

                if (!ok)
                {
                    return(false);
                }

                if (msg.Size == 0)
                {
                    //  Fall back on the auto-generation
                    byte[] buf = new byte[5];

                    buf[0] = 0;

                    byte[] result = BitConverter.GetBytes(m_nextPeerId++);

                    Buffer.BlockCopy(result, 0, buf, 1, 4);
                    identity = new Blob(buf, buf.Length);

                    msg.Close();
                }
                else
                {
                    identity = new Blob(msg.Data, msg.Size);

                    //  Ignore peers with duplicate ID.
                    if (m_outpipes.ContainsKey(identity))
                    {
                        msg.Close();
                        return(false);
                    }

                    msg.Close();
                }
            }

            pipe.Identity = identity;
            //  Add the record into output pipes lookup table
            Outpipe outpipe = new Outpipe(pipe, true);

            m_outpipes.Add(identity, outpipe);

            return(true);
        }
Пример #16
0
 /// <summary>
 /// Remove unfinished parts of the outbound message from the pipe.
 /// </summary>
 public void Rollback()
 {
     //  Remove incomplete message from the outbound pipe.
     if (m_outboundPipe != null)
     {
         var msg = new Msg();
         while (m_outboundPipe.Unwrite(ref msg))
         {
             Debug.Assert(msg.HasMore);
             msg.Close();
         }
     }
 }
Пример #17
0
        public override void Destroy()
        {
            base.Destroy();

            m_prefetchedMsg.Close();
        }
Пример #18
0
 public override void Destroy()
 {
     base.Destroy();
     m_message.Close();
 }
Пример #19
0
        protected override void ProcessPipeTermAck()
        {
            //  Notify the user that all the references to the pipe should be dropped.
            Debug.Assert(m_sink != null);
            m_sink.Terminated(this);

            //  In terminating and double_terminated states there's nothing to do.
            //  Simply deallocate the pipe. In terminated state we have to ack the
            //  peer before deallocating this side of the pipe. All the other states
            //  are invalid.
            if (m_state == State.Terminated)
            {
                m_outboundPipe = null;
                SendPipeTermAck(m_peer);
            }
            else
                Debug.Assert(m_state == State.Terminating || m_state == State.DoubleTerminated);

            //  We'll deallocate the inbound pipe, the peer will deallocate the outbound
            //  pipe (which is an inbound pipe from its point of view).
            //  First, delete all the unread messages in the pipe. We have to do it by
            //  hand because msg_t doesn't have automatic destructor. Then deallocate
            //  the ypipe itself.
            var msg = new Msg();
            while (m_inboundPipe.Read(out msg))
            {
                msg.Close();
            }

            m_inboundPipe = null;
        }
Пример #20
0
        public virtual bool PushMsg(ref Msg msg)
        {
            //  First message to receive is identity (if required).
            if (!m_identityReceived)
            {
                msg.SetFlags(MsgFlags.Identity);
                m_identityReceived = true;

                if (!m_options.RecvIdentity)
                {
                    msg.Close();
                    msg.InitEmpty();
                    return true;
                }
            }

            if (m_pipe != null && m_pipe.Write(ref msg))
            {
                msg.InitEmpty();
                return true;
            }

            return false;
        }