browsermessage-queuemessagebrokerqpid

Qpid Proton: sending messages to two destinations


Currently, I am able to send messages to a single queue "devQueue". When the message arrives to a "devQueue", it needs to be sent to the "localQueue" as well. I am finding this implementation challenging. I tried to call a different class "local_send" from "class1" class so I can connect to the other destination which is "localQueue" (as shown in the code below) but with no luck. Is there any proton function that would be useful or can I use the reference variable from on_connection_open() within "class1" class inside v_message() function? Any help or idea in this direction would be greatly appreciated.

Currently the code is not getting into "local_send" class and hence the messages are not being sent to "localQueue".

class class1 : public proton::messaging_handler {
std::string url;
std::string devQueue;
std::string localQueue;
std::vector<proton::message> msgVector;
local_send snd;
std::vector<proton::message> msgV;

public:


class1(const std::string& u, const std::string& devQueue, const std::string& localQueue) :
        url(u), devQueue(devQueue), localQueue(localQueue), snd(msgVector, localQueue) {}

void on_container_start(proton::container& c) override {
    c.connect(url);
}

void on_connection_open(proton::connection& c) override {
    c.open_receiver(devQueue);
}

void on_message(proton::delivery &d, proton::message &msg) override {
    msgV.push_back(msg);
// Here, the messages are checked if they have a valid format or not and v_message() is called
}

void v_message(const pack& msg){
    this->msgVector.push_back(msg);

//I need to send the message to localQueue and hence we are running another class from here (but that is not working :( )
    local_send snd(msgVector, localQueue);
    proton::container(snd).run();
}

void on_sendable(proton::sender &s) override {
    for(auto msg: msgVector){
        s.send(msg);
    }
}
};


// Do I even need this class to send message to another destination?

class local_send : public proton::messaging_handler {
    std::string localQueue;
    std::vector<proton::message> msgVector;

public:
    local_send(std::vector<proton::message> msgVector, const std::string& localQueue) :
        msgVector(msgVector), localQueue(localQueue) {}

void on_connection_open(proton::connection& c) override {
    c.open_receiver(localQueue);
}

void on_sendable(proton::sender &s) override {
    for(auto msg: msgVector){
        s.send(msg);
    }
}
};

Solution

  • You need to call open_sender to create a channel for sending messages. You can do this all in one handler. Pseudo code:

    proton::sender snd;
    
    on_connection_open(conn) {
        conn.open_receiver("queue1");
        snd = conn.open_sender("queue2");
    }
    
    on_message(dlv, msg) {
        // Relay message from queue1 to queue2
        snd.send(msg);
    }
    

    This snippet doesn't use on_sendable. The send is buffered in the library. If you prefer, you can use a vector of messages as you've done in your code and use on_sendable (in the same handler) to send when there's credit.