1

I am trying to send a message via a ZeroMQ PublisherSocket but I can't seem to get it right. I have tried two different approaches but both have their own problems.

SendFrame method

PublisherSocket mainSendSocket = context.CreatePublisherSocket();
mainSendSocket.Connect(...);

Then later on, I would simply call

mainSendSocket?.SendFrame(...);

This is how I would expect things to work, but the problem is I have found that sometimes I get a signifigant delay between when my WinForms application button is pressed and the message is actually sent. I know this because I am controlling some custom hardware and I get feedback right away.

Poller and SendReady event

This method doesn't have any delay but it results in the application using 100% of one CPU core. (50% of a dual core, 25% of a quad core, etc.)

PublisherSocket mainSendSocket = context.CreatePublisherSocket();
mainSendSocket.Connect(...);

poller = new Poller();
poller.AddSocket(mainSendSocket);
mainSendSocket.SendReady += mainSendSocket_SendReady;

Then in my event handler function I would use a ConcurrentQueue to check if there are any messages to be sent and send them using the same SendFrame method. When I want to send a message I would have to add the message to the queue so it is picked up by the event handler the next time it runs.

I know that the problem with the CPU usage is because the SendReady event keeps getting run as long a message can be send even if there is nothing to do but the documentation is kinda lacking on this particular area.


I'm not sure what I can do here, ideally I would like to determine the cause of the delay incurred in the first scenario but a solution to the CPU usage in the second approach or even a better third approach would be welcome.

Erik Berkun-Drevnig
  • 2,306
  • 23
  • 38
  • Regarding the send ready, I don't suggest this, as you said for publisher this event will always be raised. – somdoron Mar 09 '16 at 12:05
  • How many messages per second are you sending? How much latency do you see? Is the publisher socket is only used within the UI thread? – somdoron Mar 09 '16 at 12:06
  • It is possible that `SendFrame` may be getting called from different threads, is this okay? At most the latency is 1-2 seconds which happens maybe 10% of the time or when lots of messages are being sent. The rest of the time it is instant. – Erik Berkun-Drevnig Mar 09 '16 at 15:52
  • it might be because of the multiple threads, NetMQ socket is not thread safe. So you must send from one thread. You can your solution with the ConcurrentQueue, but instead use http://netmq.readthedocs.org/en/latest/queue/, you can poll on a queue so you don't need to use SendReady. NetMQQueue is thread safe for enqueue. So you can enqueue from multiple threads. – somdoron Mar 10 '16 at 13:05
  • Thanks, I will look into that – Erik Berkun-Drevnig Mar 11 '16 at 17:28

1 Answers1

0

You should be able to use NetMQQueue to handle messages from multiple threads. Attach it to your poller, instead of your socket and it will call ReceiveReady event once data was added to your queue. You can then directly call the Send method of your Publisher.

dwonisch
  • 5,595
  • 2
  • 30
  • 43