RabbitMQ - C++ Client #1 : Installing C/C++ Libraries

 This article documents how to connect to RabbitMQ using c/c++ to publish and subscribe to messages. I'm working on Ubuntu 20.04.

RabbitMQ supports various development languages.

Java, Python, C/C++, C#, Ruby, Javascript, as well as recently released languages such as Go and Rust are supported.

How to use various development languages is introduced in detail at https://www.rabbitmq.com/devtools.html. Those who use C/C++ can also get download information for some Client tools on this page.


<Development tool introduction page>


Install SimpleAmqpClient

In the middle of this page there is an introduction to tools for C/C++ developers.

C and C++

I'll use SimpleAmqpClient here. The reason for using SimpleAmqpClient is that the API is very concise. RabbitMQ has the advantage of being easy to port when porting Python code because the API is very similar to pika, which is widely used as a Python development tool.

Clicking the link takes you to the GitHub page https://github.com/alanxz/SimpleAmqpClient. If you look at the installation instructions, there are some things you need to install beforehand.

Pre-requisites

  • boost-1.47.0 or newer (uses chrono, system internally in addition to other header based libraries such as sharedptr and noncopyable)
  • rabbitmq-c you'll need version 0.8.0 or later. (openssl and openssl-dev should be pre-installed)
  • cmake 3.5+ is needed for the build system
  • Doxygen OPTIONAL only necessary to generate API documentation

Among them, Doxygen does not need to be installed.


Install cmake

My Ubuntu Linux has cmake 3.16.3 version already installed. If your Ubuntu doesn't have cmake, you can install it with the following command.

Ubuntu 20.04 LTS Users

sudo apt-get install cmake


CentOS 7 or 8 users

CentOS generally has lower package versions than Ubuntu. If the cmake version of CentOS is lower, download the cmake source code and build it yourself.

git clone https://github.com/Kitware/CMake.git
cd CMake
./bootstrap
make
sudo make install


Install boost-1.81.0

Source code build

As of December 2022, the latest version of boost is 1.81.0. I will download and build this version.

wget https://boostorg.jfrog.io/artifactory/main/release/1.81.0/source/boost_1_81_0.tar.gz
tar -xvzf boost_1_81_0.tar.gz
cd boost_1_81_0
sudo ./bootstrap.sh
sudo ./b2 install


Ubuntu Install Packages

apt-get install libboost-all-dev


CentOS Install Packages

yum -y install boost-devel boost


Install rabbitmq-c

SimpleAmqpClient is a wrapper of rabbitmq-c. Therefore, you need to build rabbitmq-c in advance. rabbitmq-c is the first item introduced in the C/C++ part of the developer page introduced earlier.

git clone https://github.com/alanxz/rabbitmq-c.git
cd rabbitmq-c
mkdir build
cd build
cmake ..
make
sudo make install

You can see that the following files are installed during the make install process.

Install the project...
-- Install configuration: "Release"
-- Installing: /usr/local/lib/librabbitmq.so.0.12.0
-- Installing: /usr/local/lib/librabbitmq.so.4
-- Set runtime path of "/usr/local/lib/librabbitmq.so.0.12.0" to "$ORIGIN"
-- Installing: /usr/local/lib/librabbitmq.so
-- Installing: /usr/local/lib/librabbitmq.a
-- Installing: /usr/local/include/amqp.h
-- Installing: /usr/local/include/amqp_framing.h
-- Installing: /usr/local/include/amqp_tcp_socket.h
-- Installing: /usr/local/include/amqp_ssl_socket.h
-- Installing: /usr/local/include/rabbitmq-c/amqp.h
-- Installing: /usr/local/include/rabbitmq-c/framing.h
-- Installing: /usr/local/include/rabbitmq-c/tcp_socket.h
-- Installing: /usr/local/include/rabbitmq-c/ssl_socket.h
-- Installing: /usr/local/include/rabbitmq-c/export.h
-- Installing: /usr/local/lib/cmake/rabbitmq-c/rabbitmq-c-config.cmake
-- Installing: /usr/local/lib/cmake/rabbitmq-c/rabbitmq-c-config-version.cmake
-- Installing: /usr/local/lib/cmake/rabbitmq-c/rabbitmq-targets.cmake
-- Installing: /usr/local/lib/cmake/rabbitmq-c/rabbitmq-targets-release.cmake
-- Installing: /usr/local/lib/pkgconfig/librabbitmq.pc


Now it's finally time to build SimpleAmqpClient .

Install SimpleAmqpClient 

git clone https://github.com/alanxz/SimpleAmqpClient.git
cd SimpleAmqpClient
mkdir build
cd build
cmake ..
make 
sudo make install

You can see that the following files are installed during the make install process.

Install the project...
-- Install configuration: "Release"
-- Installing: /usr/local/lib/libSimpleAmqpClient.so.7.0.1
-- Installing: /usr/local/lib/libSimpleAmqpClient.so.7
-- Set runtime path of "/usr/local/lib/libSimpleAmqpClient.so.7.0.1" to ""
-- Installing: /usr/local/lib/libSimpleAmqpClient.so
-- Installing: /usr/local/include/SimpleAmqpClient/AmqpException.h
-- Installing: /usr/local/include/SimpleAmqpClient/AmqpLibraryException.h
-- Installing: /usr/local/include/SimpleAmqpClient/AmqpResponseLibraryException.h
-- Installing: /usr/local/include/SimpleAmqpClient/BadUriException.h
-- Installing: /usr/local/include/SimpleAmqpClient/BasicMessage.h
-- Installing: /usr/local/include/SimpleAmqpClient/Channel.h
-- Installing: /usr/local/include/SimpleAmqpClient/ConnectionClosedException.h
-- Installing: /usr/local/include/SimpleAmqpClient/ConsumerCancelledException.h
-- Installing: /usr/local/include/SimpleAmqpClient/ConsumerTagNotFoundException.h
-- Installing: /usr/local/include/SimpleAmqpClient/Envelope.h
-- Installing: /usr/local/include/SimpleAmqpClient/MessageReturnedException.h
-- Installing: /usr/local/include/SimpleAmqpClient/MessageRejectedException.h
-- Installing: /usr/local/include/SimpleAmqpClient/SimpleAmqpClient.h
-- Installing: /usr/local/include/SimpleAmqpClient/Table.h
-- Installing: /usr/local/include/SimpleAmqpClient/Util.h
-- Installing: /usr/local/include/SimpleAmqpClient/Version.h
-- Installing: /usr/local/lib/pkgconfig/libSimpleAmqpClient.pc


Build example program

For testing, I ran RabbitMQ using Docker. When using Docker, the work done in MQ is not saved. Please note that restarting Docker will cause all your work to be lost. But for a simple test, there's no big problem.


Create a queue in the MQ admin page

In the MQ management page, first create a queue to be used for testing. It can be created using the API provided by SimpleAmqpClient, but it is not recommended.
Since message queues are generally used by two or more applications, creating and deleting message queues in real time is not recommended unless you are the only one using the queue.


Now, using a very simple example, we will put a message on this queue. The IP address "192.168.150.128" in the source code is the Docker server running RabbitMQ for testing.

#include <iostream>
#include <SimpleAmqpClient/SimpleAmqpClient.h>

using namespace std;
using namespace AmqpClient;

/*
All pointers are boost's smart pointers, so if the "ptr_t" variable excapes the scope, all the memories are freed and the file descripters are closed automatically.
*/
int main(int argc, char * argv[])
{
    Channel::ptr_t channel = Channel::Create("192.168.150.128", 5672);
    char szmsg[1024];

    try{
        strcpy(szmsg, "Hi I'm C++ ");
        BasicMessage::ptr_t msg = BasicMessage::Create();
        msg->Body((string)szmsg);
        channel->BasicPublish("", "SampleQueue",  msg);
    }
    catch(MessageReturnedException &e){
        std::cout << "Message delivery error: " << e.what() << std::endl;
    }

    
    return 0;

}

<my_publish.cpp>


For reference, the following is the same Python code using pika. You will see that the two codes are quite similar.

import pika

parameters = pika.ConnectionParameters(host='192.168.150.128')
connection = pika.BlockingConnection(parameters)

channel = connection.channel()
channel.basic_publish(exchange='', routing_key='SampleQueue', body="Hi I'm Python")
connection.close()

<my_publish.py>


This is the Makefile. Please note that rabbitmq and SimpoleAmqpClient are included in the link options. And these dynamic libraries are stored in /usr/local/lib. If a link error occurs, add the path to the Makefile using the -L option.

CC=g++

CFLAGS=-c -Wall -std=c++11 -g
LDFLAGS= -lpthread -lrabbitmq -lSimpleAmqpClient
SOURCES=my_publish.cpp
OBJECTS=$(SOURCES:.cpp=.o)
BACKUP=$(SOURCES:.cpp=.cpp~)

SOURCES2=my_consumer.cpp
OBJECTS2=$(SOURCES2:.cpp=.o)
BACKUP2=$(SOURCES2:.cpp=.cpp~)

EXECUTABLE=my_publish
EXECUTABLE2=my_consumer

all: publish consumer

publish: $(SOURCES) $(EXECUTABLE)
consumer: $(SOURCES2) $(EXECUTABLE2)

$(EXECUTABLE): $(OBJECTS)
	$(CC) $(OBJECTS)  $(LDFLAGS) -o $@

$(EXECUTABLE2): $(OBJECTS2)
	$(CC) $(OBJECTS2)  $(LDFLAGS) -o $@

.cpp.o:
	$(CC) -L. $(INCDIRS) $(CFLAGS) $< -o $@

clean:
	rm -f $(OBJECTS) $(EXECUTABLE) $(OBJECTS2) $(EXECUTABLE2) $(BACKUP)


Now build and test the code.

make publish
./my_publish

And in the RabbitMQ management page, you can see that a new message has been received in SampleQueue.


Wrapping up

I tested how to install SimpleAmqpClient, one of the ways to use RabbitMQ using C++, and created a simple example. Next, I'll look at how to use a Consumer program that retrieves stored messages and how to store messages in multiple queues at once using an exchange.




댓글

이 블로그의 인기 게시물

MQTT - C/C++ Client

C/C++ - Everything about time, date