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)); } }
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"); } }
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); } }
public static void Run() { using (var publisherSocket = new XPublisherSocket()) { publisherSocket.SetWelcomeMessage("WM"); publisherSocket.Bind("tcp://*:6669"); // we just drop subscriptions publisherSocket.ReceiveReady += (sender, eventArgs) => publisherSocket.SkipMultipartMessage(); var poller = new NetMQPoller { publisherSocket }; // send a message every second var sendMessageTimer = new NetMQTimer(1000); poller.Add(sendMessageTimer); sendMessageTimer.Elapsed += (sender, eventArgs) => publisherSocket.SendMoreFrame("A").SendFrame(new Random().Next().ToString()); // send heartbeat every two seconds var heartbeatTimer = new NetMQTimer(2000); poller.Add(heartbeatTimer); heartbeatTimer.Elapsed += (sender, eventArgs) => publisherSocket.SendFrame("HB"); poller.Stop(); } }
private void Work() { using (var subscriberSocket = new SubscriberSocket()) { subscriberSocket.Options.ReceiveHighWatermark = 1000; subscriberSocket.SubscribeToAnyTopic(); subscriberSocket.Connect(_toPublisherEndpoint); using (var publisherSocket = new XPublisherSocket()) { publisherSocket.Options.XPubVerbose = true; publisherSocket.Bind(_toSubscribersEndpoint); using (_poller = new NetMQPoller { new NetMQTimer(TimeSpan.FromMilliseconds(1)), subscriberSocket, publisherSocket }) { subscriberSocket.ReceiveReady += (s, e) => { var message = e.Socket.ReceiveMultipartBytes(); var topic = Encoding.UTF8.GetString(message[0]); var payload = message[1]; _cache[topic] = payload; publisherSocket.SendMultipartBytes(message); }; publisherSocket.ReceiveReady += (s, e) => { var message = e.Socket.ReceiveFrameBytes(); var isSub = message[0] == 1; var topic = Encoding.UTF8.GetString(message.Skip(1).ToArray()); if (_cache.ContainsKey(topic)) { publisherSocket.SendMoreFrame(Encoding.UTF8.GetBytes(topic)).SendFrame(_cache[topic]); } }; _poller.Run(); } } } }
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()); } }