3

I'm trying to implement the NetMQ Pub/Sub Model, but the Subscriber is not receiving any messages. What possibly is wrong here?

  private static void ServerTask()
    {
        using (var context = NetMQContext.Create())
        {
            using (var socket = context.CreateSubscriberSocket())
            {
                socket.Bind("tcp://10.120.19.109:5000");
                socket.Subscribe(string.Empty);

                while (true)
                {
                    Thread.Sleep(100);
                    string receivedMessage = socket.ReceiveString();
                    Console.WriteLine("Received: " + receivedMessage);
                }
            }
        }
    }

     public static void ClientTask()
    {
        using (NetMQContext ctx = NetMQContext.Create())
        {
            using (var socket = ctx.CreatePublisherSocket())
            {
                socket.Connect("tcp://10.120.19.109:5000");

                string obj = "hi";
                socket.Send(obj);
            }
        }
    }

Both are in different apps.

Cœur
  • 37,241
  • 25
  • 195
  • 267
user2449952
  • 581
  • 1
  • 7
  • 21

2 Answers2

4

If you are new to NetMQ I suggest reading the zeromq guide http://zguide.zeromq.org/page:all.

Bottom line is that you are sending the message before the subscriber sent the subscription.

Pubsub in zeromq and NetMQ is like radio, you will only get messages from the moment you start listen.

To simple way to do it (not a real life solution) is to sleep for some time after the connect.

For real life solution I need to understand what are you trying to achieve

Eric Boumendil
  • 2,318
  • 1
  • 27
  • 32
somdoron
  • 4,653
  • 2
  • 16
  • 24
  • I am running a serverTask() as a console app. Because subscriotion is for empty, I guess it will listen to all the subscription topic. Once its been done. I am making request to some API , which internally calls ClientTask(). As per my thinking as server is in while(true) It will keep looking into the mentioned address and it should display as soon as any message is published. – user2449952 Aug 13 '14 at 17:35
  • You may want to consider the publisher to be the server and the client to be the subscriber. Anyway as I said before Pubsub in NetMQ is like radio, if you need something else you might go for deader and router patterns. Read the guide, it will probably answer all of your questions and much more. – somdoron Aug 14 '14 at 08:00
  • You are not giving reply according to the mentioned scenario. Sorry to say but your generic sentence are of no help. Coming to your pointZeroMQ support noth N -publisher 1 sub as well as 1Publisher and nSubscriber. If you know Please tell me what's wrong in the current implementation. If u want more info I am happy to share. – user2449952 Aug 14 '14 at 09:02
  • The answer to your scenario: you are sending a message on the publisher before the subscriber send the subscription to the server. To avoid this put a sleep of 100ms after the publisher connects. in netmq the publisher filter the messages according to subscriptions, after the publisher connects the subscriber send the subscription to the publisher. however in your scenario you are sending the message before the publisher receives the client subscription. – somdoron Aug 14 '14 at 13:47
  • Thanks. It helped. But as per u suggested I can not swap Publisher and Subscriber. I need to send data from client task which is actually I am using for logging. ServerTask need to receive that data which cant be done by publisher. Which ZeroMQ model would suggest in this scenario. – user2449952 Aug 16 '14 at 03:42
  • It is a perfect push-pull pattern. Use push socket type for the client and pull socket type for the server. with that solution you won't need the sleep. – somdoron Aug 16 '14 at 11:08
  • Thanks bro. But i m having problem. Push socket Send() is waiting for Pull Socket to receive, so its not moving forward. – user2449952 Aug 18 '14 at 07:17
  • push socket will block on a send if you are not connected to any servers. You can send with dontSend set to true and will get AgainException immediately if message cannot be send. are you sure you are connecting before trying to push a message? can you upload the the push-pull code? – somdoron Aug 18 '14 at 19:50
  • yes. got It. If both Pull and Push are up . Its working smoothly. My concern was reagrding this case only. If pull is down and Only Push is up in that case case we ned to handle the exception either through dontWait or setting SendTimeOut . Right? – user2449952 Aug 19 '14 at 06:23
  • While Setting DontWait =false in pushSocket. Its not working . any idea ? Although I have made it work by setting sendTimeout . – user2449952 Aug 19 '14 at 11:05
  • you should set dontWait to true – somdoron Aug 19 '14 at 11:18
  • Sorry For Delayed Reply. I meant the same actually.. I am setting DontWait to true. Pull socket is not receiving anything. But If I implement same by time delay of say 500ms it works. – user2449952 Aug 21 '14 at 11:33
  • And my code works if I write it to implement simple program for exchanging natural number even using dontWait:true – user2449952 Aug 21 '14 at 11:44
  • can you upload the code? if the push is the one connecting I don't see a reason it won't work even if the socket is not yet connected (it should queue the message and send it when the socket is connected) – somdoron Aug 21 '14 at 13:43
  • It was becoming very clumsy ere..Posted it as a answer – user2449952 Aug 22 '14 at 06:18
0

issue is like

        using (NetMQContext ctx = NetMQContext.Create())
        {
            using (var publisher = ctx.CreatePushSocket())
            {

                publisher.Bind("tcp://localhost:5000");

                int i = 0;
                while (true)
                {
                    try
                    {

                        publisher.Send(i.ToString(), dontWait:true);
                        Console.WriteLine(i.ToString());
                    }
                    catch (Exception e)
                    {

                    }
                    finally
                    {
                        i++;
                    }

            }
        }

Now , this code works. But if I move my while(true) loop outside. and call this code from some other function Which forces push socket and context to be created as new everytime.. this doesnot work.

Vegard Larsen
  • 12,827
  • 14
  • 59
  • 102
user2449952
  • 581
  • 1
  • 7
  • 21
  • Bro I think After binding it need some time. So If I m entering Thread.Sleep (200) it started working. But I am not getting the reason. – user2449952 Aug 22 '14 at 06:55
  • In your pubsub example the publisher was the one connecting, now the publisher is doing the bind. if the publisher will do the connect everything will work fine. Now the issue is that when you bind you cannot know when somebody will connect, if you are trying to send a message while no other peers are connected the message will be dropped. – somdoron Aug 22 '14 at 07:13
  • also with NetMQ is better practice to create the context once, also creating and disposing a socket on same bind address a lot of time is not recommended and will probably won't work well. Can you create it once for all the lifetime of the system? – somdoron Aug 22 '14 at 07:15
  • pushSocket has to Bind right? so I m doin it that way Secondly I read that thing, once for all thing. I Created Context as Static but it gives error while binding sometime. :( Although I used terminate at Application_End – user2449952 Aug 22 '14 at 07:19
  • Sawpping of Bind and Connect helped man . Its working. Thanks a lot – user2449952 Aug 22 '14 at 09:23