コード例 #1
0
ファイル: Program.cs プロジェクト: bbqchickenrobot/netmq
        private static int Main(string[] args)
        {
            if (args.Length != 3)
            {
                Console.WriteLine("usage: remote_thr <connect-to> <message-size> <message-count>");
                return 1;
            }

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

            using (var context = NetMQContext.Create())
            using (var push = context.CreatePushSocket())
            {
                push.Connect(connectTo);

                for (int i = 0; i != messageCount; i++)
                {
                    var message = new Msg();
                    message.InitPool(messageSize);
                    push.Send(ref message, SendReceiveOptions.None);
                    message.Close();
                }
            }

            return 0;
        }
コード例 #2
0
ファイル: MsgTests.cs プロジェクト: wangkai2014/netmq
        public void CopyPooled()
        {
            var pool = new MockBufferPool();
            BufferPool.SetCustomBufferPool(pool);

            var msg = new Msg();
            msg.InitPool(100);

            Assert.IsFalse(msg.IsShared);

            var copy = new Msg();
            copy.Copy(ref msg);

            Assert.IsTrue(msg.IsShared);
            Assert.IsTrue(copy.IsShared);

            msg.Close();

            Assert.AreEqual(0, pool.ReturnCallCount);
            Assert.IsFalse(msg.IsInitialised);
            Assert.IsNull(msg.Data);

            copy.Close();

            Assert.AreEqual(1, pool.ReturnCallCount);
            Assert.IsFalse(copy.IsInitialised);
            Assert.IsNull(copy.Data);
        }
コード例 #3
0
ファイル: Sub.cs プロジェクト: cjkao/netmq
        /// <summary>
        /// Set the specified option on this socket - which must be either a SubScribe or an Unsubscribe.
        /// </summary>
        /// <param name="option">which option to set</param>
        /// <param name="optionValue">the value to set the option to</param>
        /// <returns><c>true</c> if successful</returns>
        /// <exception cref="InvalidException">optionValue must be a String or a byte-array.</exception>
        protected override bool XSetSocketOption(ZmqSocketOption option, object optionValue)
        {
            // Only subscribe/unsubscribe options are supported
            if (option != ZmqSocketOption.Subscribe && option != ZmqSocketOption.Unsubscribe)
                return false;

            byte[] topic;
            if (optionValue is string)
                topic = Encoding.ASCII.GetBytes((string)optionValue);
            else if (optionValue is byte[])
                topic = (byte[])optionValue;
            else
                throw new InvalidException($"In Sub.XSetSocketOption({option},{optionValue?.ToString() ?? "null"}), optionValue must be either a string or a byte-array.");

            // Create the subscription message.
            var msg = new Msg();
            msg.InitPool(topic.Length + 1);
            msg.Put(option == ZmqSocketOption.Subscribe ? (byte)1 : (byte)0);
            msg.Put(topic, 1, topic.Length);

            try
            {
                // Pass it further on in the stack.
                var isMessageSent = base.XSend(ref msg);

                if (!isMessageSent)
                    throw new Exception($"in Sub.XSetSocketOption({option}, {optionValue}), XSend returned false.");
            }
            finally
            {
                msg.Close();
            }

            return true;
        }
コード例 #4
0
        /// <summary>
        /// Transmit a byte-array of data over this socket.
        /// </summary>
        /// <param name="socket">the IOutgoingSocket to transmit on</param>
        /// <param name="data">the byte-array of data to send</param>
        /// <param name="length">the number of bytes to send from <paramref name="data"/>.</param>
        /// <param name="options">options to control how the data is sent</param>
        public static void Send([NotNull] this IOutgoingSocket socket, [NotNull] byte[] data, int length, SendReceiveOptions options)
        {
            var msg = new Msg();
            msg.InitPool(length);

            Buffer.BlockCopy(data, 0, msg.Data, 0, length);

            socket.Send(ref msg, options);

            msg.Close();
        }
コード例 #5
0
ファイル: Program.cs プロジェクト: bbqchickenrobot/netmq
        private static int Main(string[] args)
        {
            if (args.Length != 3)
            {
                Console.WriteLine("usage: local_thr <bind-to> <message-size> <message-count>");
                return 1;
            }

            string bindTo = args[0];
            int messageSize = int.Parse(args[1]);
            int messageCount = int.Parse(args[2]);

            using (var context = NetMQContext.Create())
            using (var pullSocket = context.CreatePullSocket())
            {
                pullSocket.Bind(bindTo);

                var message = new Msg();
                message.InitEmpty();

                pullSocket.Receive(ref message, SendReceiveOptions.None);

                var stopWatch = Stopwatch.StartNew();
                for (int i = 0; i != messageCount - 1; i++)
                {
                    pullSocket.Receive(ref message, SendReceiveOptions.None);
                    if (message.Size != messageSize)
                    {
                        Console.WriteLine("message of incorrect size received. Received: " + message.Size + " Expected: " + messageSize);
                        return -1;
                    }
                }
                stopWatch.Stop();
                var millisecondsElapsed = stopWatch.ElapsedMilliseconds;
                if (millisecondsElapsed == 0)
                    millisecondsElapsed = 1;

                message.Close();

                double messagesPerSecond = (double)messageCount/millisecondsElapsed*1000;
                double megabits = messagesPerSecond*messageSize*8/1000000;

                Console.WriteLine("message size: {0} [B]", messageSize);
                Console.WriteLine("message count: {0}", messageCount);
                Console.WriteLine("mean throughput: {0:0.000} [msg/s]", messagesPerSecond);
                Console.WriteLine("mean throughput: {0:0.000} [Mb/s]", megabits);

                pullSocket.Close();
            }

            return 0;
        }
コード例 #6
0
ファイル: Program.cs プロジェクト: bbqchickenrobot/netmq
        private 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]);

            using (var context = NetMQContext.Create())
            using (var req = context.CreateRequestSocket())
            {
                req.Connect(connectTo);

                var message = new Msg();
                message.InitPool(messageSize);

                var stopWatch = Stopwatch.StartNew();

                for (int i = 0; i != roundtripCount; i++)
                {
                    req.Send(ref message, SendReceiveOptions.None);

                    req.Receive(ref message, SendReceiveOptions.None);

                    if (message.Size != messageSize)
                    {
                        Console.WriteLine("message of incorrect size received. Received: {0} Expected: {1}", message.Size, messageSize);
                        return -1;
                    }
                }

                stopWatch.Stop();

                message.Close();

                double elapsedMicroseconds = stopWatch.ElapsedTicks*1000000L/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);
            }

            return 0;
        }
コード例 #7
0
        public static byte[] Receive([NotNull] this IReceivingSocket socket, SendReceiveOptions options, out bool hasMore)
        {
            var msg = new Msg();
            msg.InitEmpty();

            socket.Receive(ref msg, options);

            var data = msg.CloneData();

            hasMore = msg.HasMore;

            msg.Close();

            return data;
        }
コード例 #8
0
ファイル: QueueDevice.cs プロジェクト: romanros/netmq
        private static void ForwardTo(NetMQSocketEventArgs args, IOutgoingSocket toSocket)
        {
            var msg = new Msg();
            msg.InitEmpty();

            bool more;
            do
            {
                args.Socket.Receive(ref msg);
                more = msg.HasMore;
                toSocket.Send(ref msg, more);
            }
            while (more);

            msg.Close();
        }
コード例 #9
0
        public static void Send([NotNull] this IOutgoingSocket socket, [NotNull] string message, [NotNull] Encoding encoding, SendReceiveOptions options)
        {
            var msg = new Msg();

            // Count the number of bytes required to encode the string.
            // Note that non-ASCII strings may not have an equal number of characters
            // and bytes. The encoding must be queried for this answer.
            // With this number, request a buffer from the pool.
            msg.InitPool(encoding.GetByteCount(message));

            // Encode the string into the buffer
            encoding.GetBytes(message, 0, message.Length, msg.Data, 0);

            socket.Send(ref msg, options);

            msg.Close();
        }
コード例 #10
0
ファイル: PgmSender.cs プロジェクト: awb99/netmq
        public void Plug(IOThread ioThread, SessionBase session)
        {
            m_encoder.SetMsgSource(session);

            // get the first message from the session because we don't want to send identities
            var msg = new Msg();
            msg.InitEmpty();

            bool ok = session.PullMsg(ref msg);

            if (ok)
            {
                msg.Close();
            }

            AddSocket(m_socket);

            m_state = State.Connecting;
            m_socket.Connect(m_pgmAddress.Address);
        }
コード例 #11
0
ファイル: Dish.cs プロジェクト: zredb/netmq
        protected override void XLeave(string @group)
        {
            if (group.Length > Msg.MaxGroupLength)
            {
                throw new InvalidException("Group maximum length is 255");
            }

            if (!m_subscriptions.Remove(@group))
            {
                throw new InvalidException("Socket didn't join group");
            }

            Msg msg = new Msg();

            msg.InitLeave();
            msg.Group = group;

            m_distribution.SendToAll(ref msg);
            msg.Close();
        }
コード例 #12
0
ファイル: MsgTests.cs プロジェクト: zad15c/netmq
        public void InitDelimiter()
        {
            var msg = new Msg();

            msg.InitDelimiter();

            Assert.Equal(0, msg.Size);
            Assert.Equal(MsgType.Delimiter, msg.MsgType);
            Assert.Equal(MsgFlags.None, msg.Flags);
            Assert.Null(msg.UnsafeData);
            Assert.False(msg.HasMore);
            Assert.True(msg.IsDelimiter);
            Assert.False(msg.IsIdentity);
            Assert.True(msg.IsInitialised);

            msg.Close();

            Assert.Equal(MsgType.Uninitialised, msg.MsgType);
            Assert.Null(msg.UnsafeData);
        }
コード例 #13
0
ファイル: MsgTests.cs プロジェクト: wangkai2014/netmq
        public void InitEmpty()
        {
            var msg = new Msg();

            msg.InitEmpty();

            Assert.AreEqual(0, msg.Size);
            Assert.AreEqual(MsgType.Empty, msg.MsgType);
            Assert.AreEqual(MsgFlags.None, msg.Flags);
            Assert.IsNull(msg.Data);
            Assert.IsFalse(msg.HasMore);
            Assert.IsFalse(msg.IsDelimiter);
            Assert.IsFalse(msg.IsIdentity);
            Assert.IsTrue(msg.IsInitialised);

            msg.Close();

            Assert.AreEqual(MsgType.Uninitialised, msg.MsgType);
            Assert.IsNull(msg.Data);
        }
コード例 #14
0
ファイル: MsgTests.cs プロジェクト: xzoth/netmq
        public void InitGC()
        {
            var msg   = new Msg();
            var bytes = new byte[200];

            msg.InitGC(bytes, 100);

            Assert.AreEqual(100, msg.Size);
            Assert.AreEqual(MsgType.GC, msg.MsgType);
            Assert.AreEqual(MsgFlags.None, msg.Flags);
            Assert.AreSame(bytes, msg.Data);
            Assert.IsFalse(msg.HasMore);
            Assert.IsFalse(msg.IsDelimiter);
            Assert.IsFalse(msg.IsIdentity);
            Assert.IsTrue(msg.IsInitialised);

            msg.Close();

            Assert.AreEqual(MsgType.Uninitialised, msg.MsgType);
            Assert.IsNull(msg.Data);
        }
コード例 #15
0
ファイル: Dish.cs プロジェクト: zredb/netmq
        protected override void XJoin(string @group)
        {
            if (group.Length > Msg.MaxGroupLength)
            {
                throw new InvalidException("Group maximum length is 255");
            }

            // User cannot join same group twice
            if (!m_subscriptions.Add(@group))
            {
                throw new InvalidException("Group was already joined");
            }

            Msg msg = new Msg();

            msg.InitJoin();
            msg.Group = group;

            m_distribution.SendToAll(ref msg);
            msg.Close();
        }
コード例 #16
0
        public void Plug(IOThread ioThread, SessionBase session)
        {
            m_encoder.SetMsgSource(session);

            // get the first message from the session because we don't want to send identities
            var msg = new Msg();

            msg.InitEmpty();

            bool ok = session.PullMsg(ref msg);

            if (ok)
            {
                msg.Close();
            }

            AddSocket(m_socket);

            m_state = State.Connecting;
            m_socket.Connect(m_pgmAddress.Address);
        }
コード例 #17
0
ファイル: XPub.cs プロジェクト: rongfengliang/netmq
        /// <summary>
        /// Indicate the given pipe as being ready for reading by this socket.
        /// </summary>
        /// <param name="pipe">the <c>Pipe</c> that is now becoming available for reading</param>
        protected override void XReadActivated(Pipe pipe)
        {
            // There are some subscriptions waiting. Let's process them.
            var 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))
                {
                    if (m_manual)
                    {
                        m_lastPipe = pipe;

                        m_pending.Enqueue(sub.CloneData());
                    }
                    else
                    {
                        var unique = data[0] == 0
                            ? m_subscriptions.Remove(data, 1, size - 1, pipe)
                            : 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(sub.CloneData());
                        }
                    }
                }
                else // process message unrelated to sub/unsub
                {
                    m_pending.Enqueue(sub.CloneData());
                }

                sub.Close();
            }
        }
コード例 #18
0
        static int Main(string[] args)
        {
            if (args.Length != 3)
            {
                Console.WriteLine("usage: local_lat <bind-to> <message-size> <roundtrip-count>");
                return(1);
            }

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

            var context   = NetMQContext.Create();
            var repSocket = context.CreateResponseSocket();

            repSocket.Bind(bindTo);

            Msg message = new Msg();

            message.InitEmpty();

            for (int i = 0; i != roundtripCount; i++)
            {
                repSocket.Receive(ref message, SendReceiveOptions.None);
                if (message.Size != messageSize)
                {
                    Console.WriteLine("message of incorrect size received. Received: " + message.Size + " Expected: " + messageSize);
                    return(-1);
                }

                repSocket.Send(ref message, SendReceiveOptions.None);
            }

            message.Close();
            repSocket.Close();
            context.Terminate();

            return(0);
        }
コード例 #19
0
        public override PullMsgResult Encode(ref Msg msg)
        {
            Span <byte> messageNonce = stackalloc byte[Curve25519XSalsa20Poly1305.NonceLength];

            m_encodeNoncePrefix.CopyTo(messageNonce);
            NetworkOrderBitsConverter.PutUInt64(m_nonce, messageNonce.Slice(16));

            byte flags = 0;

            if (msg.HasMore)
            {
                flags |= 0x01;
            }
            if (msg.HasCommand)
            {
                flags |= 0x02;
            }

            Msg plaintext = new Msg();

            plaintext.InitPool(msg.Size + 1);
            plaintext[0] = flags;
            msg.CopyTo(plaintext.Slice(1));

            msg.Close();
            msg.InitPool(16 + Curve25519XSalsa20Poly1305.TagLength + plaintext.Size);

            Assumes.NotNull(m_box);

            m_box.Encrypt(msg.Slice(16), plaintext, messageNonce);
            plaintext.Close();

            MessageLiteral.CopyTo(msg);
            NetworkOrderBitsConverter.PutUInt64(m_nonce, msg.Slice(8));

            m_nonce++;
            return(PullMsgResult.Ok);
        }
コード例 #20
0
        public static NetworkMessageBase ReceiveNetworkMsg(this NetMQSocket socket, TimeSpan timeout)
        {
            var inMsg = new Msg();

            inMsg.InitEmpty();

            try
            {
                socket.TryReceive(ref inMsg, timeout);
            }
            catch (Exception)
            {
                return(null);
            }

            var str = inMsg.Size > 0
                                ? Encoding.GetString(inMsg.Data, 0, inMsg.Size)
                                : string.Empty;

            inMsg.Close();

            return(NetworkMessageCoding.Decode(str));
        }
コード例 #21
0
ファイル: Pipe.cs プロジェクト: zredb/netmq
        /// <summary>
        /// Process the pipe-termination ack.
        /// </summary>
        protected override void ProcessPipeTermAck()
        {
            // Notify the user that all the references to the pipe should be dropped.
            Assumes.NotNull(m_sink);
            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;
                Assumes.NotNull(m_peer);
                SendPipeTermAck(m_peer);
            }
            else
            {
                Debug.Assert(m_state == State.Terminating || m_state == State.DoubleTerminated);
            }

            Assumes.NotNull(m_inboundPipe);

            // 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.TryRead(out msg))
            {
                msg.Close();
            }

            m_inboundPipe = null;
        }
コード例 #22
0
        public void CopyPooled()
        {
            var pool = new MockBufferPool();

            BufferPool.SetCustomBufferPool(pool);

            var counterPool = new MockCounterPool();

            AtomicCounterPool.SetCustomCounterPool(counterPool);

            var msg = new Msg();

            msg.InitPool(100);

            Assert.False(msg.IsShared);

            var copy = new Msg();

            copy.Copy(ref msg);

            Assert.True(msg.IsShared);
            Assert.True(copy.IsShared);

            msg.Close();

            Assert.Equal(0, pool.ReturnCallCount);
            Assert.Equal(1, counterPool.ReturnCallCount);
            Assert.False(msg.IsInitialised);
            Assert.Null(msg.UnsafeData);

            copy.Close();

            Assert.Equal(1, pool.ReturnCallCount);
            Assert.Equal(2, counterPool.ReturnCallCount);
            Assert.False(copy.IsInitialised);
            Assert.Null(copy.UnsafeData);
        }
コード例 #23
0
ファイル: Program.cs プロジェクト: bbqchickenrobot/netmq
        private static int Main(string[] args)
        {
            if (args.Length != 3)
            {
                Console.WriteLine("usage: local_lat <bind-to> <message-size> <roundtrip-count>");
                return 1;
            }

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

            using (var context = NetMQContext.Create())
            using (var rep = context.CreateResponseSocket())
            {
                rep.Bind(bindTo);

                var message = new Msg();
                message.InitEmpty();

                for (int i = 0; i != roundtripCount; i++)
                {
                    rep.Receive(ref message, SendReceiveOptions.None);
                    if (message.Size != messageSize)
                    {
                        Console.WriteLine("message of incorrect size received. Received: " + message.Size + " Expected: " + messageSize);
                        return -1;
                    }

                    rep.Send(ref message, SendReceiveOptions.None);
                }

                message.Close();
            }

            return 0;
        }
コード例 #24
0
ファイル: MsgTests.cs プロジェクト: xzoth/netmq
        public void InitPool()
        {
            var pool = new MockBufferPool();

            BufferPool.SetCustomBufferPool(pool);

            var msg = new Msg();

            Assert.AreEqual(0, pool.TakeCallCount);

            msg.InitPool(100);

            Assert.AreEqual(1, pool.TakeCallCount);
            Assert.AreEqual(100, pool.TakeSize[0]);

            Assert.AreEqual(100, msg.Size);
            Assert.AreEqual(MsgType.Pool, msg.MsgType);
            Assert.AreEqual(MsgFlags.None, msg.Flags);
            Assert.IsNotNull(msg.Data);
            Assert.AreEqual(100, msg.Data.Length);
            Assert.IsFalse(msg.HasMore);
            Assert.IsFalse(msg.IsDelimiter);
            Assert.IsFalse(msg.IsIdentity);
            Assert.IsTrue(msg.IsInitialised);

            Assert.AreEqual(0, pool.ReturnCallCount);

            var bytes = msg.Data;

            msg.Close();

            Assert.AreEqual(1, pool.ReturnCallCount);
            Assert.AreSame(bytes, pool.ReturnBuffer[0]);

            Assert.AreEqual(MsgType.Uninitialised, msg.MsgType);
            Assert.IsNull(msg.Data);
        }
コード例 #25
0
        /// <summary>
        /// Remove any half processed messages. Flush unflushed messages.
        /// Call this function when engine disconnect to get rid of leftovers.
        /// </summary>
        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();
                }
            }
        }
コード例 #26
0
        static XSub()
        {
            s_sendSubscription = (data, size, arg) =>
            {
                var pipe = (Pipe)arg;

                // Create the subscription message.
                var msg = new Msg();
                msg.InitPool(size + 1);
                msg.Put(1);
                msg.Put(data, 1, size);

                // Send it to the pipe.
                bool sent = pipe.Write(ref 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();
                }
            };
        }
コード例 #27
0
        public static bool SendNetworkMsg(this NetMQSocket socket, NetworkMessageBase message,
                                          uint timeoutMilliSeconds = GlobalConstants.StandardSendingTimeout)
        {
            var encodedMessage = NetworkMessageCoding.Encode(message);

            var outMsg = new Msg();

            outMsg.InitPool(Encoding.GetByteCount(encodedMessage));
            Encoding.GetBytes(encodedMessage, 0, encodedMessage.Length, outMsg.Data, 0);

            bool sendSuccessful;

            try
            {
                sendSuccessful = socket.TrySend(ref outMsg, TimeSpan.FromMilliseconds(timeoutMilliSeconds), false);
            }
            catch (Exception)
            {
                sendSuccessful = false;
            }

            outMsg.Close();
            return(sendSuccessful);
        }
コード例 #28
0
ファイル: Radio.cs プロジェクト: zredb/netmq
        protected override void XReadActivated(Pipe pipe)
        {
            // There are some subscriptions waiting. Let's process them.
            Msg msg = new Msg();

            while (pipe.Read(ref msg))
            {
                // Apply the subscription to the trie
                if (msg.IsJoin || msg.IsLeave)
                {
                    if (msg.IsJoin)
                    {
                        if (!m_subscriptions.TryGetValue(msg.Group, out var pipes))
                        {
                            pipes = new HashSet <Pipe>();
                            m_subscriptions.Add(msg.Group, pipes);
                        }

                        pipes.Add(pipe);
                    }
                    else
                    {
                        if (m_subscriptions.TryGetValue(msg.Group, out var pipes))
                        {
                            pipes.Remove(pipe);
                            if (!pipes.Any())
                            {
                                m_subscriptions.Remove(msg.Group);
                            }
                        }
                    }
                }

                msg.Close();
            }
        }
コード例 #29
0
        /// <summary>
        /// This method is called to assign the specified pipe as a replacement for the outbound pipe that was being used.
        /// </summary>
        /// <param name="pipe">the pipe to use for writing</param>
        /// <remarks>
        /// A "Hiccup" occurs when an outbound pipe experiences something like a transient disconnect or for whatever other reason
        /// is no longer available for writing to.
        /// </remarks>
        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.TryRead(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);
            }
        }
コード例 #30
0
        /// <summary>
        /// 将所有消息帧原封不动的发送至另外一端
        /// </summary>
        /// <param name="from"></param>
        /// <param name="to"></param>
        /// <param name="control"></param>
        private static void ProxyBetween(IReceivingSocket from, IOutgoingSocket to, IOutgoingSocket control)
        {
            Msg msg = default(Msg);

            msg.InitEmpty();
            Msg msg2 = default(Msg);

            msg2.InitEmpty();
            bool hasMore;

            do
            {
                from.Receive(ref msg);
                hasMore = msg.HasMore;
                if (control != null)
                {
                    msg2.Copy(ref msg);
                    control.Send(ref msg2, hasMore);
                }
                to.Send(ref msg, hasMore);
            }while (hasMore);
            msg2.Close();
            msg.Close();
        }
コード例 #31
0
        private static int Main(string[] args)
        {
            if (args.Length != 3)
            {
                Console.WriteLine("usage: local_lat <bind-to> <message-size> <roundtrip-count>");
                return(1);
            }

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

            using (var rep = new ResponseSocket())
            {
                rep.Bind(bindTo);

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

                for (int i = 0; i != roundtripCount; i++)
                {
                    rep.Receive(ref msg);
                    if (msg.Size != messageSize)
                    {
                        Console.WriteLine("message of incorrect size received. Received: " + msg.Size + " Expected: " + messageSize);
                        return(-1);
                    }

                    rep.Send(ref msg, more: false);
                }

                msg.Close();
            }

            return(0);
        }
コード例 #32
0
        /// <summary>
        /// Write the given Msg to the pipe.
        /// </summary>
        /// <param name="msg">the Msg to push to the pipe</param>
        /// <returns>true if the Msg was successfully sent</returns>
        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);
        }
コード例 #33
0
ファイル: Router.cs プロジェクト: awb99/netmq
        private bool IdentifyPeer( Pipe pipe)
        {
            byte[] identity;

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

                var 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
                    identity = new byte[5];

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

                    Buffer.BlockCopy(result, 0, identity, 1, 4);

                    msg.Close();
                }
                else
                {
                    identity = msg.CloneData();

                    // 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
            var outpipe = new Outpipe(pipe, true);
            m_outpipes.Add(identity, outpipe);

            return true;
        }
コード例 #34
0
ファイル: XPub.cs プロジェクト: wangkai2014/netmq
        /// <summary>
        /// Receive a message. The <c>Recv</c> method calls this lower-level method to do the actual receiving.
        /// </summary>
        /// <param name="msg">the <c>Msg</c> to receive the message into</param>
        /// <returns><c>true</c> if the message was received successfully, <c>false</c> if there were no messages to receive</returns>
        protected override bool XRecv(ref Msg msg)
        {
            // If there is at least one
            if (m_pending.Count == 0)
                return false;

            msg.Close();

            byte[] first = m_pending.Dequeue();
            msg.InitPool(first.Length);

            msg.Put(first, 0, first.Length);

            return true;
        }
コード例 #35
0
ファイル: SessionBase.cs プロジェクト: sharpe5/netmq
        /// <summary>
        /// Remove any half processed messages. Flush unflushed messages.
        /// Call this function when engine disconnect to get rid of leftovers.
        /// </summary>
        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();
                }
            }
        }
コード例 #36
0
ファイル: Sub.cs プロジェクト: sharpe5/netmq
        /// <summary>
        /// Set the specified option on this socket - which must be either a SubScribe or an Unsubscribe.
        /// </summary>
        /// <param name="option">which option to set</param>
        /// <param name="optionValue">the value to set the option to</param>
        /// <returns><c>true</c> if successful</returns>
        /// <exception cref="InvalidException">optionValue must be a String or a byte-array.</exception>
        /// <exception cref="AgainException">XSend must return true.</exception>
        protected override bool XSetSocketOption(ZmqSocketOption option, object optionValue)
        {
            // Only subscribe/unsubscribe options are supported
            if (option != ZmqSocketOption.Subscribe && option != ZmqSocketOption.Unsubscribe)
                return false;

            byte[] topic;
            if (optionValue is string)
                topic = Encoding.ASCII.GetBytes((string)optionValue);
            else if (optionValue is byte[])
                topic = (byte[])optionValue;
            else
                throw new InvalidException(string.Format("In Sub.XSetSocketOption({0},{1}), optionValue must be either a string or a byte-array.", option, (optionValue == null ? "null" : optionValue.ToString())));

            // Create the subscription message.
            var msg = new Msg();
            msg.InitPool(topic.Length + 1);
            msg.Put(option == ZmqSocketOption.Subscribe ? (byte)1 : (byte)0);
            msg.Put(topic, 1, topic.Length);

            try
            {
                // Pass it further on in the stack.
                bool isMessageSent = base.XSend(ref msg);

                if (!isMessageSent)
                {
                    string xMsg = string.Format("in Sub.XSetSocketOption({0}, {1}), XSend returned false.", option, optionValue);
                    // TODO: should we change the exception that is thrown here as AgainException is obsolete?
#pragma warning disable 618                    
                    throw new AgainException(innerException: null, message: xMsg);
#pragma warning restore 618
                }
            }
            finally
            {
                msg.Close();
            }

            return true;
        }
コード例 #37
0
ファイル: Router.cs プロジェクト: stojy/netmq
        private bool IdentifyPeer([NotNull] Pipe pipe)
        {
            byte[] identity;

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

                var 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
                    identity = new byte[5];

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

                    Buffer.BlockCopy(result, 0, identity, 1, 4);

                    msg.Close();
                }
                else
                {
                    identity = msg.CloneData();
                    msg.Close();

                    Outpipe existPipe;

                    if (m_outpipes.TryGetValue(identity, out existPipe))
                    {
                        if (!m_handover)
                        {
                            // Ignore peers with duplicate ID.
                            return(false);
                        }
                        else
                        {
                            //  We will allow the new connection to take over this
                            //  identity. Temporarily assign a new identity to the
                            //  existing pipe so we can terminate it asynchronously.
                            var    newIdentity = new byte[5];
                            byte[] result      = BitConverter.GetBytes(m_nextPeerId++);
                            Buffer.BlockCopy(result, 0, newIdentity, 1, 4);
                            existPipe.Pipe.Identity = newIdentity;
                            m_outpipes.Add(newIdentity, existPipe);

                            //  Remove the existing identity entry to allow the new
                            //  connection to take the identity.
                            m_outpipes.Remove(identity);

                            if (existPipe.Pipe == m_currentIn)
                            {
                                m_closingCurrentIn = true;
                            }
                            else
                            {
                                existPipe.Pipe.Terminate(true);
                            }
                        }
                    }
                }
            }

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

            m_outpipes.Add(identity, outpipe);

            return(true);
        }
コード例 #38
0
        /// <summary>
        /// Send the Example to the socket.
        /// </summary>
        public void Send(IOutgoingSocket output)
        {
            if (output is RouterSocket)
            {
                output.SendMoreFrame(RoutingId);
            }

            int frameSize = 2 + 1;                      //  Signature and message ID

            switch (Id)
            {
            case MessageId.Log:
                frameSize += Log.GetFrameSize();
                break;

            case MessageId.Structures:
                frameSize += Structures.GetFrameSize();
                break;

            case MessageId.Binary:
                frameSize += Binary.GetFrameSize();
                break;

            case MessageId.Types:
                frameSize += Types.GetFrameSize();
                break;
            }

            //  Now serialize message into the buffer
            Msg msg = new Msg();

            msg.InitPool(frameSize);

            try
            {
                m_offset = 0;
                m_buffer = msg.Data;

                // put signature
                PutNumber2(0xAAA0 | 0);

                // put message id
                PutNumber1((byte)Id);

                switch (Id)
                {
                case MessageId.Log:
                    Log.Write(this);
                    break;

                case MessageId.Structures:
                    Structures.Write(this);
                    break;

                case MessageId.Binary:
                    Binary.Write(this);
                    break;

                case MessageId.Types:
                    Types.Write(this);
                    break;
                }

                //  Send the data frame
                output.Send(ref msg, false);
            }
            finally
            {
                m_buffer = null;
                msg.Close();
            }
        }
コード例 #39
0
        /// <summary>
        /// Transmit the given message. The <c>Send</c> method calls this to do the actual sending.
        /// </summary>
        /// <param name="msg">the message to transmit</param>
        /// <returns><c>true</c> if the message was sent successfully</returns>
        /// <exception cref="HostUnreachableException">The receiving host must be identifiable.</exception>
        protected override bool XSend(ref Msg msg)
        {
            // If this is the first part of the message it's the ID of the
            // peer to send the message to.
            if (m_sendingState == State.RoutingId)
            {
                Debug.Assert(m_currentOut == null);

                // If we have malformed message (prefix with no subsequent message)
                // then just silently ignore it.
                if (msg.HasMore)
                {
                    // Find the pipe associated with the routingId stored in the prefix.
                    var routingId = msg.UnsafeToArray();

                    if (m_outpipes.TryGetValue(routingId, out Outpipe op))
                    {
                        m_currentOut = op.Pipe;
                        if (!m_currentOut.CheckWrite())
                        {
                            op.Active    = false;
                            m_currentOut = null;

                            if (!op.Pipe.Active)
                            {
                                throw new HostUnreachableException("In Peer.XSend");
                            }

                            return(false);
                        }
                    }
                    else
                    {
                        throw new HostUnreachableException("In Peer.XSend");
                    }

                    m_sendingState = State.Data;
                }

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

                return(true);
            }

            m_sendingState = State.RoutingId;

            //  Peer sockets do not allow multipart data (ZMQ_SNDMORE)
            if (msg.HasMore)
            {
                throw new InvalidException();
            }

            // Push the message into the pipe. If there's no out pipe, just drop it.
            if (m_currentOut != null)
            {
                bool ok = m_currentOut.Write(ref msg);

                if (ok)
                {
                    m_currentOut.Flush();
                }

                m_currentOut = null;
            }
            else
            {
                msg.Close();
            }

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

            return(true);
        }
コード例 #40
0
ファイル: Pipe.cs プロジェクト: vordoom/netmq
        /// <summary>
        /// Process the pipe-termination ack.
        /// </summary>
        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.TryRead(out msg))
            {
                msg.Close();
            }

            m_inboundPipe = null;
        }
コード例 #41
0
ファイル: Pipe.cs プロジェクト: vordoom/netmq
        /// <summary>
        /// This method is called to assign the specified pipe as a replacement for the outbound pipe that was being used.
        /// </summary>
        /// <param name="pipe">the pipe to use for writing</param>
        /// <remarks>
        /// A "Hiccup" occurs when an outbound pipe experiences something like a transient disconnect or for whatever other reason
        /// is no longer available for writing to.
        /// </remarks>
        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.TryRead(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);
        }
コード例 #42
0
ファイル: Pipe.cs プロジェクト: vordoom/netmq
 /// <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();
         }
     }
 }
コード例 #43
0
ファイル: XSub.cs プロジェクト: wangkai2014/netmq
        static XSub()
        {
            s_sendSubscription = (data, size, arg) =>
            {
                var pipe = (Pipe)arg;

                // Create the subscription message.
                var msg = new Msg();
                msg.InitPool(size + 1);
                msg.Put(1);
                msg.Put(data, 1, size);

                // Send it to the pipe.
                bool sent = pipe.Write(ref 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();
            };
        }
コード例 #44
0
ファイル: XPub.cs プロジェクト: b-cuts/netmq
        /// <summary>
        /// Indicate the given pipe as being ready for reading by this socket.
        /// </summary>
        /// <param name="pipe">the <c>Pipe</c> that is now becoming available for reading</param>
        protected override void XReadActivated(Pipe pipe)
        {
            // There are some subscriptions waiting. Let's process them.
            var sub = new Msg();
            var isBroadcast = false;
            while (pipe.Read(ref sub))
            {
                // Apply the subscription to the trie.
                int size = sub.Size;
                if (size > 0 && (sub[0] == 0 || sub[0] == 1) && !isBroadcast)
                {
                    if (m_manual)
                    {
                        m_pendingMessages.Enqueue(new KeyValuePair<Msg,Pipe>(sub, pipe));
                    }
                    else
                    {
                        var unique = sub[0] == 0
                            ? m_subscriptions.Remove(sub.Data, sub.Offset + 1, size - 1, pipe)
                            : m_subscriptions.Add(sub.Data, sub.Offset + 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_pendingMessages.Enqueue(new KeyValuePair<Msg, Pipe>(sub, null));
                        }
                        else
                        {
                            sub.Close();
                        }

                    }
                }
                else if (m_broadcastEnabled && size > 0 && sub[0] == 2)
                {
                    m_pendingMessages.Enqueue(new KeyValuePair<Msg, Pipe>(sub, pipe));
                    isBroadcast = true;
                }
                else // process message unrelated to sub/unsub
                {
                    // pipe is null here, no special treatment
                    m_pendingMessages.Enqueue(new KeyValuePair<Msg, Pipe>(sub, null));
                }

            }
        }
コード例 #45
0
ファイル: XPub.cs プロジェクト: b-cuts/netmq
 /// <summary>
 /// Receive a message. The <c>Recv</c> method calls this lower-level method to do the actual receiving.
 /// </summary>
 /// <param name="msg">the <c>Msg</c> to receive the message into</param>
 /// <returns><c>true</c> if the message was received successfully, <c>false</c> if there were no messages to receive</returns>
 protected override bool XRecv(ref Msg msg)
 {
     // If there is at least one
     if (m_pendingMessages.Count == 0)
         return false;
     msg.Close();
     var msgPipe = m_pendingMessages.Dequeue();
     msg = msgPipe.Key;
     // must check if m_lastPipe == null to avoid dequeue at the second frame of a broadcast message
     if (msgPipe.Value != null && m_lastPipe == null)
     {
         if (m_broadcastEnabled && msg[0] == 2)
         {
             m_lastPipeIsBroadcast = true;
             m_lastPipe = msgPipe.Value;
         }
         if (m_manual && (msg[0] == 0 || msg[0] == 1))
         {
             m_lastPipeIsBroadcast = false;
             m_lastPipe = msgPipe.Value;
         }
     }
     return true;
 }
コード例 #46
0
ファイル: XSub.cs プロジェクト: wangkai2014/netmq
        /// <summary>
        /// Transmit the given message. The <c>Send</c> method calls this to do the actual sending.
        /// </summary>
        /// <param name="msg">the message to transmit</param>
        /// <returns><c>true</c> if the message was sent successfully</returns>
        protected override bool XSend(ref Msg msg)
        {
            byte[] data = msg.Data;
            int size = msg.Size;

            if (size > 0 && data[0] == 1)
            {
                // Process the subscription.
                if (m_subscriptions.Add(data, 1, size - 1))
                {
                    m_distribution.SendToAll(ref msg);
                    return true;
                }
            }
            else if (size > 0 && data[0] == 0)
            {
                if (m_subscriptions.Remove(data, 1, size - 1))
                {
                    m_distribution.SendToAll(ref msg);
                    return true;
                }
            }
            else
            {
                // upstream message unrelated to sub/unsub
                m_distribution.SendToAll(ref msg);

                return true;
            }

            msg.Close();
            msg.InitEmpty();

            return true;
        }
コード例 #47
0
        /// <summary>
        /// Receive a Example from the socket.
        /// </summary>
        public void Receive(IReceivingSocket input)
        {
            bool more;

            if (input is RouterSocket)
            {
                Msg routingIdMsg = new Msg();
                routingIdMsg.InitEmpty();

                try
                {
                    input.Receive(ref routingIdMsg);

                    if (!routingIdMsg.HasMore)
                    {
                        throw new MessageException("No routing id");
                    }

                    if (m_routingId == null || m_routingId.Length == routingIdMsg.Size)
                    {
                        m_routingId = new byte[routingIdMsg.Size];
                    }

                    Buffer.BlockCopy(routingIdMsg.Data, 0, m_routingId, 0, m_routingId.Length);
                }
                finally
                {
                    routingIdMsg.Close();
                }
            }
            else
            {
                RoutingId = null;
            }

            Msg msg = new Msg();

            msg.InitEmpty();

            try
            {
                input.Receive(ref msg);

                m_offset = 0;
                m_buffer = msg.Data;
                more     = msg.HasMore;

                UInt16 signature = GetNumber2();

                if (signature != (0xAAA0 | 0))
                {
                    throw new MessageException("Invalid signature");
                }

                //  Get message id and parse per message type
                Id = (MessageId)GetNumber1();

                switch (Id)
                {
                case MessageId.Log:
                    Log.Read(this);
                    break;

                case MessageId.Structures:
                    Structures.Read(this);
                    break;

                case MessageId.Binary:
                    Binary.Read(this);
                    break;

                case MessageId.Types:
                    Types.Read(this);
                    break;

                default:
                    throw new MessageException("Bad message id");
                }
            }
            finally
            {
                m_buffer = null;
                msg.Close();
            }
        }
コード例 #48
0
ファイル: Distribution.cs プロジェクト: bbqchickenrobot/netmq
        /// <summary>
        /// Put the message to all active pipes.
        /// </summary>
        private void Distribute(ref Msg msg)
        {
            //  If there are no matching pipes available, simply drop the message.
            if (m_matching == 0)
            {
                msg.Close();
                msg.InitEmpty();

                return;
            }

            if (msg.MsgType != MsgType.Pool)
            {
                for (int i = 0; i < m_matching; ++i)
                {
                    if (!Write(m_pipes[i], ref msg))
                    {
                        --i; //  Retry last write because index will have been swapped
                    }
                }

                msg.Close();
                msg.InitEmpty();

                return;
            }

            //  Add matching-1 references to the message. We already hold one reference,
            //  that's why -1.
            msg.AddReferences(m_matching - 1);

            //  Push copy of the message to each matching pipe.
            int failed = 0;
            for (int i = 0; i < m_matching; ++i)
            {
                if (!Write(m_pipes[i], ref msg))
                {
                    ++failed;
                    --i; //  Retry last write because index will have been swapped
                }
            }
            if (failed != 0)
                msg.RemoveReferences(failed);

            //  Detach the original message from the data buffer. Note that we don't
            //  close the message. That's because we've already used all the references.
            msg.InitEmpty();
        }
コード例 #49
0
ファイル: LoadBalancer.cs プロジェクト: awb99/netmq
        public bool Send(ref Msg msg)
        {
            // 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();
                msg.InitEmpty();
                return true;
            }

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

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

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

            // If it's part of the message we can flush 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;
            }

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

            return true;
        }
コード例 #50
0
ファイル: FairQueueing.cs プロジェクト: bbqchickenrobot/netmq
        public bool RecvPipe(Pipe[] pipe, ref Msg msg)
        {
            //  Deallocate old content of the message.
            msg.Close();

            //  Round-robin over the pipes to get the next message.
            while (m_active > 0)
            {

                //  Try to fetch new message. If we've already read part of the message
                //  subsequent part should be immediately available.
                bool fetched = m_pipes[m_current].Read(ref msg);

                //  Note that when message is not fetched, current pipe is deactivated
                //  and replaced by another active pipe. Thus we don't have to increase
                //  the 'current' pointer.
                if (fetched)
                {
                    if (pipe != null)
                        pipe[0] = m_pipes[m_current];
                    m_more = msg.HasMore;
                    if (!m_more)
                        m_current = (m_current + 1) % m_active;
                    return true;
                }

                //  Check the atomicity of the message.
                //  If we've already received the first part of the message
                //  we should get the remaining parts without blocking.
                Debug.Assert(!m_more);

                m_active--;
                m_pipes.Swap(m_current, m_active);
                if (m_current == m_active)
                    m_current = 0;
            }

            //  No message is available. Initialise the output parameter
            //  to be a 0-byte message.
            msg.InitEmpty();
            return false;
        }
コード例 #51
0
ファイル: Req.cs プロジェクト: wangkai2014/netmq
        /// <summary>
        /// Receive a message. The <c>Recv</c> method calls this lower-level method to do the actual receiving.
        /// </summary>
        /// <param name="msg">the <c>Msg</c> to receive the message into</param>
        /// <returns><c>true</c> if the message was received successfully, <c>false</c> if there were no messages to receive</returns>
        /// <exception cref="FiniteStateMachineException">Req.XRecv expecting send, not receive.</exception>
        protected override bool XRecv(ref Msg msg)
        {
            bool isMessageAvailable;

            // If request wasn't send, we can't wait for reply.
            if (!m_receivingReply)
                throw new FiniteStateMachineException("Req.XRecv - cannot receive another reply");

            // First part of the reply should be the original request ID.
            if (m_messageBegins)
            {
                isMessageAvailable = base.XRecv(ref msg);

                if (!isMessageAvailable)
                    return false;

                if (!msg.HasMore || msg.Size != 0)
                {
                    while (true)
                    {
                        isMessageAvailable = base.XRecv(ref msg);
                        Debug.Assert(isMessageAvailable);
                        if (!msg.HasMore)
                            break;
                    }

                    msg.Close();
                    msg.InitEmpty();
                    return false;
                }

                m_messageBegins = false;
            }

            isMessageAvailable = base.XRecv(ref msg);
            if (!isMessageAvailable)
                return false;

            // If the reply is fully received, flip the FSM into request-sending state.
            if (!msg.HasMore)
            {
                m_receivingReply = false;
                m_messageBegins = true;
            }

            return true;
        }
コード例 #52
0
ファイル: Proxy.cs プロジェクト: bbqchickenrobot/netmq
        private static void ProxyBetween(NetMQSocket from, NetMQSocket to, [CanBeNull] NetMQSocket control)
        {
            var msg = new Msg();
            msg.InitEmpty();

            var copy = new Msg();
            copy.InitEmpty();

            while (true)
            {
                from.Receive(ref msg, SendReceiveOptions.None);
                bool more = from.Options.ReceiveMore;

                if (control != null)
                {
                    copy.Copy(ref msg);

                    control.Send(ref copy, more ? SendReceiveOptions.SendMore : SendReceiveOptions.None);
                }

                to.Send(ref msg, more ? SendReceiveOptions.SendMore : SendReceiveOptions.None);

                if (!more)
                {
                    break;
                }
            }

            copy.Close();
            msg.Close();
        }
コード例 #53
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.

                    byte[] identity = msg.Data;

                    if (msg.Size != msg.Data.Length)
                    {
                        identity = new byte[msg.Size];
                        Buffer.BlockCopy(msg.Data, 0, identity, 0, 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 new HostUnreachableException("In Router.XSend");
                    }
                }

                //  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);
        }
コード例 #54
0
ファイル: Router.cs プロジェクト: awb99/netmq
        /// <summary>
        /// Transmit the given message. The <c>Send</c> method calls this to do the actual sending.
        /// </summary>
        /// <param name="msg">the message to transmit</param>
        /// <returns><c>true</c> if the message was sent successfully</returns>
        /// <exception cref="HostUnreachableException">The receiving host must be identifiable.</exception>
        protected override bool XSend(ref Msg msg)
        {
            // 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.

                    var identity = msg.Size == msg.Data.Length 
                        ? msg.Data
                        : msg.CloneData();

                    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 new HostUnreachableException("In Router.XSend");
                    }
                }

                // 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;
        }
コード例 #55
0
        /// <summary>
        ///     Transmit the given message. The <c>Send</c> method calls this to do the actual sending.
        /// </summary>
        /// <param name="msg">the message to transmit</param>
        /// <returns><c>true</c> if the message was sent successfully</returns>
        /// <exception cref="HostUnreachableException">In Stream.XSend</exception>
        protected override bool XSend(ref Msg msg)
        {
            // If this is the first part of the message it's the ID of the
            // peer to send the message to.
            if (!this.m_moreOut)
            {
                Debug.Assert(this.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)
                {
                    // 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.

                    byte[] identity = msg.Size == msg.Data.Length
                        ? msg.Data
                        : msg.CloneData();

                    Outpipe op;
                    if (this.m_outpipes.TryGetValue(identity, out op))
                    {
                        this.m_currentOut = op.Pipe;
                        if (!this.m_currentOut.CheckWrite())
                        {
                            op.Active         = false;
                            this.m_currentOut = null;
                            return(false);
                        }
                    }
                    else
                    {
                        throw new HostUnreachableException("In Stream.XSend");
                    }
                }

                this.m_moreOut = true;

                msg.Close();
                msg.InitEmpty();

                return(true);
            }

            // Ignore the MORE flag
            msg.ResetFlags(MsgFlags.More);

            // This is the last part of the message.
            this.m_moreOut = false;

            // Push the message into the pipe. If there's no out pipe, just drop it.
            if (this.m_currentOut != null)
            {
                if (msg.Size == 0)
                {
                    this.m_currentOut.Terminate(false);
                    this.m_currentOut = null;
                    return(true);
                }

                bool ok = this.m_currentOut.Write(ref msg);
                if (ok)
                {
                    this.m_currentOut.Flush();
                }

                this.m_currentOut = null;
            }

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

            return(true);
        }
コード例 #56
0
ファイル: SessionBase.cs プロジェクト: sharpe5/netmq
        /// <summary>
        /// Write the given Msg to the pipe.
        /// </summary>
        /// <param name="msg">the Msg to push to the pipe</param>
        /// <returns>true if the Msg was successfully sent</returns>
        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;
        }
コード例 #57
0
 public override void Destroy()
 {
     base.Destroy();
     m_prefetchedId.Close();
     m_prefetchedMsg.Close();
 }
コード例 #58
0
 public override void Destroy()
 {
     base.Destroy();
     m_message.Close();
 }
コード例 #59
0
        private bool IdentifyPeer([NotNull] Pipe pipe)
        {
            byte[] identity;

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

                var 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
                    identity    = new byte[5];
                    identity[0] = 0;

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

                    Buffer.BlockCopy(result, 0, identity, 1, 4);

                    msg.Close();
                }
                else
                {
                    identity = new byte[msg.Size];
                    Buffer.BlockCopy(msg.Data, 0, identity, 0, 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
            var outpipe = new Outpipe(pipe, true);

            m_outpipes.Add(identity, outpipe);

            return(true);
        }
コード例 #60
0
ファイル: ThroughputBenchmark.cs プロジェクト: awb99/netmq
        protected override void Produce(PushSocket socket, int messageSize)
        {
            var msg = new Msg();

            for (int i = 0; i < MsgCount; i++)
            {
                msg.InitGC(new byte[messageSize], messageSize);
                msg.Data[messageSize / 2] = 0x42;

                socket.Send(ref msg, more: false);

                msg.Close();
            }
        }