Pages

Improved sending for zmq::Socket

Minor change in zmq::Socket, my C++ zmq::socket_t subclass for ZeroMQ version 2. Now it is possible to send a multipart message, up to three frames, calling a send() overload that expects in input the frames as raw C-strings or STL string.

Before the change, if we want to send more frames in a single call, we had to go through a vector, like this:
zmq::Frames frames;
frames.reserve(3);
frames.push_back(id);
frames.push_back("");
frames.push_back(payload);
socket_.send(frames);
It was boring to write code like this, and the result was not very readable.

Now we can get the same result in a single line:
socket_.send(id, "", payload);
It is not a big change in the code. I changed slightly the original send() function, and moved it in the private class section:
bool send(const char* frame, size_t len, int flags =0)
{
    zmq::message_t msg(len);
    memcpy(msg.data(), frame, len);
    return socket_t::send(msg, flags);
}
Some more information on zmq::Socket is available in a previous post.

The main change at this level is in the fact that the message length is now passed as an input parameter.

In the public interface, the one-frame-at-the-time functions become:
bool send(const std::string& frame, int flags =0)
{
    return send(frame.c_str(), frame.length(), flags);
}

bool send(const char* frame, int flags =0)
{
    return send(frame, strlen(frame), flags);
}
If we pass a STL string, its size is already known, cached in the object, so we use it. Otherwise it is calculated by a call to strlen(). When we use these overload we should explicitly say if we consider the current frame as part (and not the last one) of a multipart message.

The two- and three-part messages could be now be sent with a single call. Let's see the three-part by c-string parameter overload:
bool send(const char* frame1, const char* frame2, const char* frame3)
{
    if(!send(frame1, ZMQ_SNDMORE))
        return false;
    if(!send(frame2, ZMQ_SNDMORE))
        return false;
    // last frame
    return send(frame3);
}
The first two frames are sent with the SNDMORE flag, going through above descripted single-frame overload, the last one is terminating the sequence.

The improved include file is on github.

No comments:

Post a Comment