SimpleAmqpClient Documentation

repository·master·Indexed 19 days ago

https://github.com/alanxz/simpleamqpclient

A C++ wrapper around the rabbitmq-c C library that simplifies AMQP development by abstracting channels into error and consumer scopes. It provides the AmqpClient::Channel class for broker connections, BasicMessage for message configuration, and a comprehensive exception hierarchy (AmqpException, ChannelException, ConnectionException) to distinguish between recoverable soft errors and non-recoverable hard errors.

Tokens
9.1K
Snippets
29
Records
41
Agent score
65%

What's inside SimpleAmqpClient

  1. How AmqpClient::Channel works

    master

    The AmqpClient::Channel class is the primary interface for the library. It abstracts AMQP channels into an error/consumer scope and represents a connection to an AMQP broker.

    Key Behaviors

    • Connection: A connection is established automatically upon constructing an instance of the class.
    • Object Creation: All classes in the library provide a Create() method and a ptr_t typedef (equivalent to boost::shared_ptr<>). It is recommended to use Create() to instantiate objects.
    • Error Handling:
      • AmqpClient::ChannelException: Thrown during commands like declaring/binding/unbinding/deleting exchanges or queues. The Channel object remains usable after this exception.
      • AmqpClient::ConnectionException or AmqpClient::AmqpResponseLibraryException: Thrown during severe errors. The Channel object is no longer usable after these exceptions.
    AmqpClient::Channel::ptr_t connection = AmqpClient::Channel::Create("localhost");
  2. Install SimpleAmqpClient on Windows

    master

    Building on Windows requires Boost libraries and rabbitmq-c built as a shared library.

    1. Install Boost via NuGet

    Install the following components (example using version 1.77.0 and MSVC 14.2):

    nuget install boost_chrono-vc142 -Version 1.77.0
    nuget install boost_system-vc142 -Version 1.77.0
    nuget install boost -Version 1.77.0

    2. Build with CMake

    Use the CMake CLI to configure the project. You must provide paths to your Boost and rabbitmq-c installations.

    Example Configuration (assuming Boost is in C:/boost and rabbitmq-c is in C:/rabbitmq-c):

    cmake -G "Visual Studio 16" -A x64 \
    -DBoost_INCLUDE_DIR="C:/boost.XX.XX.X.X/lib/native/include" \
    -DBOOST_ROOT="C:/boost.X.XX.X.X" \
    -DBOOST_LIBRARYDIR="C:/boost" \
    -DRabbitmqc_INCLUDE_DIR="C:/rabbitmq-c/include" \
    -DRabbitmqc_LIBRARY="C:/rabbitmq-c/lib/rabbitmq.4.lib" \
    -DBoost_USE_STATIC_LIBS=ON \
    -DBUILD_STATIC_LIBS=ON \
    -DENABLE_SSL_SUPPORT=OFF ..
    cmake -G "Visual Studio 16" -A x64 -DBoost_INCLUDE_DIR="C:/boost.XX.XX.X.X/lib/native/include" -DBOOST_ROOT="C:/boost.X.XX.X.X" -DBOOST_LIBRARYDIR="C:/boost" -DRabbitmqc_INCLUDE_DIR="C:/rabbitmq-c/include" -DRabbitmqc_LIBRARY="C:/rabbitmq-c/lib/rabbitmq.4.lib" -DBoost_USE_STATIC_LIBS=ON -DBUILD_STATIC_LIBS=ON -DENABLE_SSL_SUPPORT=OFF ..
  3. Consume messages using AmqpClient::Channel

    master

    To consume messages, you must first set up a consumer using BasicConsume, which returns a consumer tag. This tag is then used for subsequent operations like receiving messages, setting QoS, or canceling the consumer.

    Workflow

    1. Start Consumer: Call BasicConsume(queue_name, consumer_properties) to get a consumer_tag.
    2. Receive Message: Use BasicConsumeMessage(consumer_tag) to retrieve an Envelope.
    3. Acknowledge: Call BasicAck(envelope) to acknowledge the message.
    4. Cancel: Call BasicCancel(consumer_tag) to stop consuming.
    std::string consumer_tag = channel->BasicConsume("my_queue", "");
    Envelope::ptr_t envelope = channel->BasicConsumeMessage(consumer_tag);
    // To ack:
    channel->BasicAck(envelope);
    // To cancel:
    channel->BasicCancel(consumer_tag);
  4. Install SimpleAmqpClient via CMake

    master

    SimpleAmqpClient is a CMake-based project. To build it, create a build directory in a sibling directory to the source code and run CMake.

    Build Steps

    1. Create and enter a build directory:
      mkdir simpleamqpclient-build
      cd simpleamqpclient-build
    2. Run CMake:
      cmake ..
    3. Use your system's build utility (e.g., make or msbuild) to compile the library.

    CMake Targets

    • test: Builds and runs the test suite. (Note: Enable the Google-test suite by passing -DENABLE_TESTING=ON to CMake).
    • install: Installs headers and the library to the defined CMAKE_INSTALL_PREFIX.
    • doc: Generates API documentation using Doxygen (if installed).
    mkdir simpleamqpclient-build
    cd simpleamqpclient-build
    cmake ..
  5. Pre-requisites for SimpleAmqpClient

    master

    Before building, ensure the following dependencies are available:

    • boost: Version 1.47.0 or newer (requires chrono and system).
    • rabbitmq-c: Version 0.8.0 or better.
    • cmake: Version 3.5 or newer.
    • Doxygen (Optional): Required only if you wish to generate API documentation.
  6. Distinguish between soft and hard AMQP errors

    master

    When handling exceptions, you can determine if an error is recoverable by calling is_soft_error() on an AmqpException object:

    • Soft Errors (is_soft_error() == true): These are generally recoverable. The Channel object that originated the error can still be reused. These derive from AmqpClient::ChannelException.
    • Hard Errors (is_soft_error() == false): These are non-recoverable. The Channel object is closed and will throw exceptions if used again. These derive from AmqpClient::ConnectionException.
  7. Use delivery_mode_t for message persistence

    master

    The AmqpClient::BasicMessage::delivery_mode_t enum defines how a message should be handled by durable queues regarding persistence.

    • dm_notset (0): No delivery mode specified.
    • dm_nonpersistent (1): The message is not persistent.
    • dm_persistent (2): The message should be persisted to disk.
    msg->DeliveryMode(AmqpClient::BasicMessage::dm_persistent);
  8. Understand AMQP Table and TableValue structures

    master

    In SimpleAmqpClient, AMQP tables (used for arguments in exchanges, queues, etc.) are represented using a Table type, which is a std::map of TableKey (a std::string) to TableValue objects.

    TableValue is a variant type that can hold various AMQP-compatible data types. Because RabbitMQ does not support unsigned 64-bit values in tables, TableValue provides a Timestamp type (using std::time_t) to handle such values.

    Key types supported by TableValue include:

    • Booleans
    • Integers (8, 16, 32, and 64-bit signed; 8, 16, and 32-bit unsigned)
    • Floating point (float, double)
    • Strings
    • Arrays (std::vector<TableValue>)
    • Tables (AmqpClient::Table)
    • Timestamps (std::time_t)
  9. Use the AmqpClient::Envelope class

    master

    The AmqpClient::Envelope class represents an AMQP message envelope. It bundles the actual message payload (BasicMessage) with delivery metadata provided by the broker, such as the delivery tag, exchange, routing key, and consumer tag. This is the object typically received when consuming messages from a queue.

    Key metadata available via the envelope:

    • Message: The BasicMessage::ptr_t containing the payload.
    • DeliveryTag: A unique uint64_t assigned by the broker for a specific delivery on a specific channel. This tag is required when acknowledging (Ack'ing) a message.
    • ConsumerTag: The tag identifying the consumer to which the message was delivered.
    • Exchange: The name of the exchange the message was published to.
    • RoutingKey: The routing key used during publication.
    • Redelivered: A boolean flag indicating if the message was previously unacknowledged and subsequently redelivered.
    • DeliveryChannel: The ID of the channel on which the delivery occurred.
    // Example of accessing envelope metadata
    AmqpClient::Envelope::ptr_t envelope = /* received from consumer */;
    
    auto message = envelope->Message();
    auto tag = envelope->DeliveryTag();
    auto exchange = envelope->Exchange();
    auto routing_key = envelope->RoutingKey();
    bool is_redelivered = envelope->Redelivered();
  10. Use BasicConsumeMessage with timeout

    master

    You can use a blocking version of BasicConsumeMessage that accepts a timeout (in milliseconds) to prevent the thread from hanging indefinitely if no message arrives.

    Envelope::ptr_t envelope;
    channel->BasicConsumeMessage(consumer_tag, envelope, 10); // 10 ms timeout
  11. Handle ConsumerCancelledException

    master

    The AmqpClient::ConsumerCancelledException is thrown when the AMQP server terminates a consumer subscription. This typically occurs in two scenarios:

    1. The server ends the subscription because the subscribed queue is being deleted.
    2. The client itself issues a basic.cancel request.

    You can catch this exception to identify which consumer was affected by calling GetConsumerTag() on the exception object.

    try {
        // Code that performs consuming operations
    } catch (const AmqpClient::ConsumerCancelledException& e) {
        std::string tag = e.GetConsumerTag();
        // Handle the cancellation for this specific consumer tag
    }