예제 #1
0
        public void Unsubscribe()
        {
            using (var pub = new XPublisherSocket())
                using (var sub = new XSubscriberSocket())
                {
                    var port = pub.BindRandomPort("tcp://127.0.0.1");
                    sub.Connect("tcp://127.0.0.1:" + port);
                    sub.SendFrame(new byte[] { 1, (byte)'A' });

                    // let the subscriber connect to the publisher before sending a message
                    Thread.Sleep(500);

                    pub.SendMoreFrame("A");
                    pub.SendFrame("Hello");

                    bool more;

                    Assert.AreEqual("A", sub.ReceiveFrameString(out more));
                    Assert.IsTrue(more);

                    Assert.AreEqual("Hello", sub.ReceiveFrameString(out more));
                    Assert.False(more);

                    sub.SendFrame(new byte[] { 0, (byte)'A' });

                    Thread.Sleep(500);

                    pub.SendMoreFrame("A");
                    pub.SendFrame("Hello");

                    string str;
                    Assert.IsFalse(sub.TryReceiveFrameString(out str));
                }
        }
예제 #2
0
        public void MultipleSubscribers()
        {
            using (var pub = new XPublisherSocket())
                using (var sub = new XSubscriberSocket())
                    using (var sub2 = new XSubscriberSocket())
                    {
                        var port = pub.BindRandomPort("tcp://127.0.0.1");

                        sub.Connect("tcp://127.0.0.1:" + port);
                        sub.SendFrame(new byte[] { 1, (byte)'A' });
                        sub.SendFrame(new byte[] { 1, (byte)'A', (byte)'B' });
                        sub.SendFrame(new byte[] { 1, (byte)'B' });
                        sub.SendFrame(new byte[] { 1, (byte)'C' });

                        sub2.Connect("tcp://127.0.0.1:" + port);
                        sub2.SendFrame(new byte[] { 1, (byte)'A' });
                        sub2.SendFrame(new byte[] { 1, (byte)'A', (byte)'B' });
                        sub2.SendFrame(new byte[] { 1, (byte)'C' });

                        Thread.Sleep(500);

                        pub.SendMoreFrame("AB");
                        pub.SendFrame("1");

                        Assert.AreEqual("AB", sub.ReceiveMultipartStrings().First(), "First subscriber is expected to receive the message");

                        Assert.AreEqual("AB", sub2.ReceiveMultipartStrings().First(), "Second subscriber is expected to receive the message");
                    }
        }
예제 #3
0
        public void TopicPubSub()
        {
            using (var pub = new XPublisherSocket())
                using (var sub = new XSubscriberSocket())
                {
                    var port = pub.BindRandomPort("tcp://127.0.0.1");
                    sub.Connect("tcp://127.0.0.1:" + port);
                    sub.SendFrame(new byte[] { 1, (byte)'A' });

                    // let the subscriber connect to the publisher before sending a message
                    Thread.Sleep(500);

                    var msg = pub.ReceiveFrameBytes();
                    Assert.AreEqual(2, msg.Length);
                    Assert.AreEqual(1, msg[0]);
                    Assert.AreEqual('A', msg[1]);

                    pub.SendMoreFrame("A");
                    pub.SendFrame("Hello");

                    bool more;

                    Assert.AreEqual("A", sub.ReceiveFrameString(out more));
                    Assert.IsTrue(more);

                    Assert.AreEqual("Hello", sub.ReceiveFrameString(out more));
                    Assert.False(more);
                }
        }
예제 #4
0
        public void MultipleSubscriptions()
        {
            using (var pub = new XPublisherSocket())
                using (var sub = new XSubscriberSocket())
                {
                    var port = pub.BindRandomPort("tcp://127.0.0.1");
                    sub.Connect("tcp://127.0.0.1:" + port);

                    sub.SendFrame(new byte[] { 1, (byte)'C' });
                    sub.SendFrame(new byte[] { 1, (byte)'B' });
                    sub.SendFrame(new byte[] { 1, (byte)'A' });
                    sub.SendFrame(new byte[] { 1, (byte)'D' });
                    sub.SendFrame(new byte[] { 1, (byte)'E' });

                    Thread.Sleep(500);

                    sub.SendFrame(new byte[] { 0, (byte)'C' });
                    sub.SendFrame(new byte[] { 0, (byte)'B' });
                    sub.SendFrame(new byte[] { 0, (byte)'A' });
                    sub.SendFrame(new byte[] { 0, (byte)'D' });
                    sub.SendFrame(new byte[] { 0, (byte)'E' });

                    Thread.Sleep(500);
                }
        }
예제 #5
0
        public void ThroughXPubXSubWithReconnectingPublisher()
        {
            using (var xpub = new XPublisherSocket())
                using (var xsub = new XSubscriberSocket())
                    using (var poller = new NetMQPoller {
                        xsub, xpub
                    })
                    {
                        var xPubPort = (ushort)xpub.BindRandomPort("tcp://*");
                        var xSubPort = (ushort)xsub.BindRandomPort("tcp://*");

                        var proxy = new Proxy(xsub, xpub, poller: poller);
                        proxy.Start();

                        poller.RunAsync();

                        // long running subscriber
                        using (var sub = new SubscriberSocket())
                        {
                            sub.Connect(string.Format("tcp://localhost:{0}", xPubPort));
                            sub.Subscribe("A");

                            // publisher 1
                            using (var pub = new PublisherSocket())
                            {
                                pub.Connect(string.Format("tcp://localhost:{0}", xSubPort));
                                // give the publisher a chance to learn of the subscription
                                Thread.Sleep(100);
                                pub.SendMoreFrame("A").SendFrame("1");
                            }

                            // publisher 2
                            using (var pub = new PublisherSocket())
                            {
                                pub.Connect(string.Format("tcp://localhost:{0}", xSubPort));
                                // give the publisher a chance to learn of the subscription
                                Thread.Sleep(100);
                                pub.SendMoreFrame("A").SendFrame("2");
                            }

                            var frames = new List <string>();

                            Assert.True(sub.TryReceiveMultipartStrings(TimeSpan.FromSeconds(1), ref frames));
                            CollectionAssert.AreEqual(new[] { "A", "1" }, frames);

                            Assert.True(sub.TryReceiveMultipartStrings(TimeSpan.FromSeconds(1), ref frames));
                            CollectionAssert.AreEqual(new[] { "A", "2" }, frames);
                        }
                    }
        }
예제 #6
0
        public void NotSubscribed()
        {
            using (var pub = new XPublisherSocket())
                using (var sub = new XSubscriberSocket())
                {
                    var port = pub.BindRandomPort("tcp://127.0.0.1");
                    sub.Connect("tcp://127.0.0.1:" + port);

                    // let the subscriber connect to the publisher before sending a message
                    Thread.Sleep(500);

                    pub.SendFrame("Hello");

                    Assert.IsFalse(sub.TrySkipFrame());
                }
        }
예제 #7
0
        public void SimplePubSub()
        {
            using (var pub = new XPublisherSocket())
                using (var sub = new XSubscriberSocket())
                {
                    var port = pub.BindRandomPort("tcp://127.0.0.1");
                    sub.Connect("tcp://127.0.0.1:" + port);
                    sub.SendFrame(new byte[] { 1 });

                    // let the subscriber connect to the publisher before sending a message
                    Thread.Sleep(500);

                    pub.SendFrame("Hello");

                    Assert.AreEqual("Hello", sub.ReceiveFrameString(out bool more));
                    Assert.False(more);
                }
        }
예제 #8
0
        public void Census()
        {
            using (var pub = new XPublisherSocket())
                using (var sub = new XSubscriberSocket())
                {
                    var port = pub.BindRandomPort("tcp://127.0.0.1");

                    sub.Connect("tcp://127.0.0.1:" + port);
                    sub.SendFrame("Message from subscriber");

                    // let the subscriber connect to the publisher before sending a message
                    Thread.Sleep(500);

                    var txt = pub.ReceiveFrameString();
                    Assert.AreEqual("Message from subscriber", txt);

                    sub.SendFrame(new byte[] { });

                    var msg = pub.ReceiveFrameBytes();
                    Assert.True(msg.Length == 0);
                }
        }
예제 #9
0
        public void ThroughXPubXSub()
        {
            using (var xpub = new XPublisherSocket())
                using (var xsub = new XSubscriberSocket())
                    using (var proxyPoller = new NetMQPoller {
                        xsub, xpub
                    })
                    {
                        var xPubPort = (ushort)xpub.BindRandomPort("tcp://*");
                        var xSubPort = (ushort)xsub.BindRandomPort("tcp://*");

                        var proxy = new Proxy(xsub, xpub, poller: proxyPoller);
                        proxy.Start();

                        proxyPoller.RunAsync();

                        using (var pub = new PublisherSocket())
                            using (var sub = new SubscriberSocket())
                            {
                                // Client 1
                                sub.Connect(string.Format("tcp://localhost:{0}", xPubPort));
                                pub.Connect(string.Format("tcp://localhost:{0}", xSubPort));

                                sub.Subscribe("A");

                                // Client 2
                                Thread.Sleep(500);
                                pub.SendMoreFrame("A").SendFrame("Hello");

                                var frames = new List <string>();
                                Assert.True(sub.TryReceiveMultipartStrings(TimeSpan.FromSeconds(1), ref frames));
                                CollectionAssert.AreEqual(
                                    new[] { "A", "Hello" },
                                    frames);
                            }
                    }
        }
예제 #10
0
        public void MultiplePublishers()
        {
            using (var pub = new XPublisherSocket())
                using (var pub2 = new XPublisherSocket())
                    using (var sub = new XSubscriberSocket())
                        using (var sub2 = new XSubscriberSocket())
                        {
                            var port  = pub.BindRandomPort("tcp://127.0.0.1");
                            var port2 = pub2.BindRandomPort("tcp://127.0.0.1");

                            // see comments below why verbose option is needed in this test
                            pub.Options.XPubVerbose  = true;
                            pub2.Options.XPubVerbose = true;

                            sub.Connect("tcp://127.0.0.1:" + port);
                            sub.Connect("tcp://127.0.0.1:" + port2);

                            sub2.Connect("tcp://127.0.0.1:" + port);
                            sub2.Connect("tcp://127.0.0.1:" + port2);

                            // should subscribe to both
                            sub.SendFrame(new byte[] { 1, (byte)'A' });
                            sub2.SendFrame(new byte[] { 1, (byte)'A' });

                            Thread.Sleep(500);

                            var msg = pub.ReceiveFrameString();
                            Assert.AreEqual(2, msg.Length);
                            Assert.AreEqual(1, msg[0]);
                            Assert.AreEqual('A', msg[1]);

                            var msg2 = pub2.ReceiveFrameBytes();
                            Assert.AreEqual(2, msg2.Length);
                            Assert.AreEqual(1, msg2[0]);
                            Assert.AreEqual('A', msg2[1]);


                            // Next two blocks (pub(2).Receive) will hang without XPub verbose option:
                            // sub and sub2 both have sent `.Send(new byte[] { 1, (byte)'A' });` messages
                            // which are the same, so XPub will discard the second message for .Receive()
                            // because it is normally used to pass topics upstream.
                            // (un)subs are done in XPub.cs at line 150-175, quote:
                            // >> If the subscription is not a duplicate, store it so that it can be
                            // >> passed to used on next recv call.
                            // For verbose:
                            // >> If true, send all subscription messages upstream, not just unique ones

                            // These options must be set before sub2.Send(new byte[] { 1, (byte)'A' });
                            // pub.Options.XPubVerbose = true;
                            // pub2.Options.XPubVerbose = true;
                            // Note that resending sub2.Send(..) here wont help because XSub won't resent existing subs to XPub - quite sane behavior
                            // Comment out the verbose options and the next 8 lines and the test will
                            // still pass, even with non-unique messages from subscribers (see the bottom of the test)

                            msg = pub.ReceiveFrameString();
                            Assert.AreEqual(2, msg.Length);
                            Assert.AreEqual(1, msg[0]);
                            Assert.AreEqual('A', msg[1]);

                            msg2 = pub2.ReceiveFrameBytes();
                            Assert.AreEqual(2, msg2.Length);
                            Assert.AreEqual(1, msg2[0]);
                            Assert.AreEqual('A', msg2[1]);


                            pub.SendMoreFrame("A");
                            pub.SendFrame("Hello from the first publisher");

                            bool more;
                            Assert.AreEqual("A", sub.ReceiveFrameString(out more));
                            Assert.IsTrue(more);
                            Assert.AreEqual("Hello from the first publisher", sub.ReceiveFrameString(out more));
                            Assert.False(more);
                            // this returns the result of the latest
                            // connect - address2, not the source of the message
                            // This is documented here: http://api.zeromq.org/3-2:zmq-getsockopt
                            //var ep = sub2.Options.LastEndpoint;
                            //Assert.AreEqual(address, ep);

                            // same for sub2
                            Assert.AreEqual("A", sub2.ReceiveFrameString(out more));
                            Assert.IsTrue(more);
                            Assert.AreEqual("Hello from the first publisher", sub2.ReceiveFrameString(out more));
                            Assert.False(more);


                            pub2.SendMoreFrame("A");
                            pub2.SendFrame("Hello from the second publisher");

                            Assert.AreEqual("A", sub.ReceiveFrameString(out more));
                            Assert.IsTrue(more);

                            Assert.AreEqual("Hello from the second publisher", sub.ReceiveFrameString(out more));
                            Assert.False(more);
                            Assert.AreEqual("tcp://127.0.0.1:" + port2, sub2.Options.LastEndpoint);


                            // same for sub2
                            Assert.AreEqual("A", sub2.ReceiveFrameString(out more));
                            Assert.IsTrue(more);
                            Assert.AreEqual("Hello from the second publisher", sub2.ReceiveFrameString(out more));
                            Assert.False(more);

                            // send both to address and address2
                            sub.SendFrame("Message from subscriber");
                            sub2.SendFrame("Message from subscriber 2");

                            Assert.AreEqual("Message from subscriber", pub.ReceiveFrameString());
                            Assert.AreEqual("Message from subscriber", pub2.ReceiveFrameString());

                            // Does not hang even though is the same as above, but the first byte is not 1 or 0.
                            // Won't hang even when messages are equal
                            Assert.AreEqual("Message from subscriber 2", pub.ReceiveFrameString());
                            Assert.AreEqual("Message from subscriber 2", pub2.ReceiveFrameString());
                        }
        }