Chip Brommer
Chip Brommer

Reputation: 168

ZMQCPP using socket_t as class variable

I'm creating a class to handle ZMQCPP that I can use within several different projects. I want to have the context_t and socket_t be a class variable so I do not have to pass them around to different functions as parameters (what I currently do). But I keep getting errors and am unsure if this is even possible.

I've looked through the zmq.hpp file and not seeing a "Default" null constructor for socket_t class without needing a context and socket type off the bat.

Any input or guidance would be appreciated.

Here is my current class setup

#include "zmq_addon.hpp"
#include <zmq.h>

#define DEFAULT_IP "tcp://127.0.0.1:"
#define DEFAULT_PORT 5555

class zmqClientTCP {
    public:
        zmqClientTCP();                     // Default Constructor
        ~zmqClientTCP();                    // Deconstructor
        int setAddress(std::string);        // Changes the IP Address. 
        int setPortNumber(int);             // Change port number explicitly
        int setSocketType(int);             // Change the socket type
        int connect();                      // Connects 
        void disconnect();                  // Disconnects from active connection
        void sendMessage(std::string*);     // Send Message over connection. 

    private:
        std::string ipAddress = "";         // Holds the IP Address
        int portNum = -1;                   // Holds port number
        int sockType = ZMQ_SUB;             // Set socket type for ZMQ connection
        const zmq::context_t context;       // ZMQ Context for single thread
        zmq::socket_t socket;               // ZMQ Socket 
        bool isConnected = false;           // Bool for connection. 
};

Class implementation: (what I would like to do)

int zmqClientTCP::connect() {
    socket(context, sockType);
    socket.connect(ipAddress);

    // MONITOR IMPLEMENTATION HERE

    if(isConnected)return 1;

    return 0
}

void sendMessage(std::string msg){
    zmq::message_t zOut(msg);
    socket.send(zOut, zmq::send_flags::none);
}

void zmqClientTCP::disconnect() {
    socket.disconnect(ipAddress);
}

Class Implementation (What I currently do):

int zmqClientTCP::connect() {
    zmq::context_t context;
    zmq::socket_t socket(context, sockType);
    socket.connect(ipAddress);
    std::string temp

    /*   MONITOR IS HERE TO TRIGGER isConnected BOOL */

    while(isConnected){
       temp.clear();
       std::getline(std::cin, temp);
       sendMessage(socket, temp);
    }

    disconnect(socket);

    return 1;
}

void sendMessage(zmq::socket_t &socket, std::string msg){
    zmq::message_t zOut(msg);
    socket.send(zOut, zmq::send_flags::none);
}

void zmqClientTCP::disconnect(zmq::socket_t &socket) {
    socket.disconnect(ipAddress);
}

Upvotes: 0

Views: 846

Answers (1)

Chip Brommer
Chip Brommer

Reputation: 168

For anyone that comes across this; I was able to achieve my desire by using ZMQ C++ API functionality. You'll need the "zmq_addons.hpp".

class zmqClientTCP {
public:
    zmqClientTCP();                     // Default Constructor
    ~zmqClientTCP();                    // Deconstructor
    void connect();                     // Connects to address
    void disconnect();                  // Disconnects from active connection
    void sendMessage(const std::string*);// Send string over connection. 
    void sendMessage(const char*);      // Send c style string over connection. 
    void recvMessage(std::string*);     // Recv message over connection. 

private:
    void* context;                      // ZMQ Context for single thread
    void* socket;                       // ZMQ Socket 
    char buffer[256];                   // Buffer for message receiving
};

Here is the basic functionality to accompany the class.

void zmqClientTCP::connect() {
    context = zmq_ctx_new();
    socket = zmq_socket(context, ZMQ_REQ);
    zmq_connect(socket, ipAddress+PortNum);
}

void zmqClientTCP::sendMessage(const std::string* msg) {
    zmq_send(socket, _strdup(msg->c_str()), strlen(msg->c_str()), 0);
}

void zmqClientTCP::sendMessage(const char* msg) {
    zmq_send(socket, _strdup(msg), strlen(msg), 0);
}

void zmqClientTCP::recvMessage(std::string* msg) {
    // Clear buffer 
    memset(buffer, '\0', sizeof(buffer));
    // Recv message from zmq into the buffer 
    zmq_recv(socket, buffer, sizeof(buffer), 0);
    // Convert buffer to string
    std::string temp(buffer);
    // Assign temp string to inbound string parameter. 
    msg->assign(temp);
}

void zmqClientTCP::disconnect() {
    zmq_close(socket);
    zmq_term(context);

}

Then you can just write easy class implementation like so:

zmqClientTCP zmqClient;
zmqClient.connect();
std::string msgOut = "Hello World";
zmqClient.sendMessage(&msgOut);
std::string msgIn = "";
zmqClient.recvMessage(&msgIn);
zmqClient.disconnect();

Upvotes: 1

Related Questions