ZMQ Radio/Dish cannot send multi-part message

Viewed 478

I try to send a multi-part message on a ZMQ Radio socket but I get an EINVAL error (Invalid argument). Here is the code which sends the first part of the message:

#include <iostream>
#include <cstring>
#include "ZmqRadio.h"

using namespace std;

int main() {

  auto addr = "udp://127.0.0.1:4444";
  auto myGroup = "myGroup";
  std::string data = "Hello";

  void *context = zmq_ctx_new();
  void *radio = zmq_socket(context, ZMQ_RADIO);
  zmq_connect(radio, addr);

  zmq_msg_t msg;
  zmq_msg_init_size(&msg, 5);
  zmq_msg_set_group(&msg, myGroup);

  memcpy(zmq_msg_data(&msg), &data[0], 5);

  int rc = zmq_msg_send(&msg, radio, ZMQ_SNDMORE);
  if (rc == -1) {
    int err = zmq_errno();
    cout << "Error: " << err << endl;
  }
}

In this case the return code of zmq_msg_send is -1 and zmq_errno() returns 22 (EINVAL).

If I replace the send command with:

int rc = zmq_msg_send(&msg, radio, 0);

Then I got rc=6 and I am able to read the (single part) message via my Dish socket.

Can you help me to point what's going wrong?

1 Answers

ZMQ_RADIO, ZMQ_DISH pattern uses zeromq thread safe sockets. Thread safe sockets do not support multipart messages.

From : http://api.zeromq.org/4-3:zmq-socket

ZMQ_RADIO sockets are threadsafe. They do not accept the ZMQ_SNDMORE option on sends. This limits them to single part data.

You have two options.

  • Use another message structure to pack your frames (msgpack maybe) then send over RADIO DISH as a single message.
  • Switch to ZMQ_PUB/ZMQ_SUB. The downside here is you will need to use TCP or PGM as the transport.
Related