예제 #1
0
        private bool xxrecv(SendReceiveOptions flags, ref Msg msg)
        {
            //  If there is a prefetched message, return it.
            if (m_prefetched)
            {
                msg.Move(ref m_prefetchedMsg);

                m_prefetched = false;

                return(true);
            }

            //  DEALER socket doesn't use identities. We can safely drop it and
            while (true)
            {
                bool isMessageAvailable = m_fq.Recv(ref msg);

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

                if ((msg.Flags & MsgFlags.Identity) == 0)
                {
                    break;
                }
            }

            return(true);
        }
예제 #2
0
        protected override bool XRecv(SendReceiveOptions flags, ref Msg msg)
        {
            if (m_prefetched)
            {
                if (!m_identitySent)
                {
                    msg.Move(ref m_prefetchedId);
                    m_identitySent = true;
                }
                else
                {
                    msg.Move(ref m_prefetchedMsg);
                    m_prefetched = false;
                }

                return(true);
            }

            Pipe[] pipe = new Pipe[1];

            bool isMessageAvailable = m_fq.RecvPipe(pipe, ref m_prefetchedMsg);

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

            Debug.Assert(pipe[0] != null);
            Debug.Assert(!m_prefetchedMsg.HasMore);

            //  We have received a frame with TCP data.
            //  Rather than sendig this frame, we keep it in prefetched
            //  buffer and send a frame with peer's ID.
            Blob identity = pipe[0].Identity;

            msg.InitPool(identity.Size);
            msg.Put(identity.Data, 0, identity.Size);
            msg.SetFlags(MsgFlags.More);

            m_prefetched   = true;
            m_identitySent = true;

            return(true);
        }
예제 #3
0
        protected override bool XRecv(SendReceiveOptions flags, ref Msg msg)
        {
            //  If there's already a message prepared by a previous call to zmq_poll,
            //  return it straight ahead.

            if (m_hasMessage)
            {
                msg.Move(ref m_message);
                m_hasMessage = false;
                m_more       = msg.HasMore;
                return(true);
            }

            //  TODO: This can result in infinite loop in the case of continuous
            //  stream of non-matching messages which breaks the non-blocking recv
            //  semantics.
            while (true)
            {
                //  Get a message using fair queueing algorithm.
                bool isMessageAvailable = m_fq.Recv(ref msg);

                //  If there's no message available, return immediately.
                //  The same when error occurs.
                if (!isMessageAvailable)
                {
                    return(false);
                }

                //  Check whether the message matches at least one subscription.
                //  Non-initial parts of the message are passed
                if (m_more || !m_options.Filter || Match(msg))
                {
                    m_more = msg.HasMore;
                    return(true);
                }

                //  Message doesn't match. Pop any remaining parts of the message
                //  from the pipe.
                while (msg.HasMore)
                {
                    isMessageAvailable = m_fq.Recv(ref msg);

                    Debug.Assert(isMessageAvailable);
                }
            }
        }
예제 #4
0
        protected override bool XRecv(SendReceiveOptions flags, ref Msg msg)
        {
            if (m_prefetched)
            {
                if (!m_identitySent)
                {
                    msg.Move(ref m_prefetchedId);
                    m_identitySent = true;
                }
                else
                {
                    msg.Move(ref m_prefetchedMsg);
                    m_prefetched = false;
                }
                m_moreIn = msg.HasMore;
                return(true);
            }

            Pipe[] pipe = new Pipe[1];

            bool isMessageAvailable = m_fq.RecvPipe(pipe, ref msg);

            //  It's possible that we receive peer's identity. That happens
            //  after reconnection. The current implementation assumes that
            //  the peer always uses the same identity.
            //  TODO: handle the situation when the peer changes its identity.
            while (isMessageAvailable && msg.IsIdentity)
            {
                isMessageAvailable = m_fq.RecvPipe(pipe, ref msg);
            }

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

            Debug.Assert(pipe[0] != null);

            //  If we are in the middle of reading a message, just return the next part.
            if (m_moreIn)
            {
                m_moreIn = msg.HasMore;
            }
            else
            {
                //  We are at the beginning of a message.
                //  Keep the message part we have in the prefetch buffer
                //  and return the ID of the peer instead.
                m_prefetchedMsg.Move(ref msg);

                m_prefetched = true;

                Blob identity = pipe[0].Identity;
                msg.InitPool(identity.Size);
                msg.Put(identity.Data, 0, identity.Size);
                msg.SetFlags(MsgFlags.More);

                m_identitySent = true;
            }

            return(true);
        }