Merge branch 'readme' into clean-build
This commit is contained in:
commit
144ec66e61
180
README.md
180
README.md
|
|
@ -9,33 +9,33 @@ AMQP-CPP is a C++ library for communicating with a RabbitMQ message broker. The
|
||||||
library can be used to parse incoming data from a RabbitMQ server, and to
|
library can be used to parse incoming data from a RabbitMQ server, and to
|
||||||
generate frames that can be sent to a RabbitMQ server.
|
generate frames that can be sent to a RabbitMQ server.
|
||||||
|
|
||||||
This library has a layered architecture, and allows you - if you like - to
|
This library has a layered architecture, and allows you - if you like - to
|
||||||
completely take care of the network layer. If you want to set up and manage the
|
completely take care of the network layer. If you want to set up and manage the
|
||||||
network connections yourself, the AMQP-CPP library will not make a connection to
|
network connections yourself, the AMQP-CPP library will not make a connection to
|
||||||
RabbitMQ by itself, nor will it create sockets and/or perform IO operations. As
|
RabbitMQ by itself, nor will it create sockets and/or perform IO operations. As
|
||||||
a user of this library, you create the socket connection and implement a certain
|
a user of this library, you create the socket connection and implement a certain
|
||||||
interface that you pass to the AMQP-CPP library and that the library will use
|
interface that you pass to the AMQP-CPP library and that the library will use
|
||||||
for IO operations.
|
for IO operations.
|
||||||
|
|
||||||
Intercepting this network layer is however optional, the AMQP-CPP library also
|
Intercepting this network layer is however optional, the AMQP-CPP library also
|
||||||
comes with a predefined Tcp module that can be used if you trust the AMQP library
|
comes with a predefined Tcp module that can be used if you trust the AMQP library
|
||||||
to take care of the network handling. In that case, the AMQP-CPP library does
|
to take care of the network handling. In that case, the AMQP-CPP library does
|
||||||
all the system calls to set up network connections and send and receive the data.
|
all the system calls to set up network connections and send and receive the data.
|
||||||
|
|
||||||
This layered architecture makes the library extremely flexible and portable: it
|
This layered architecture makes the library extremely flexible and portable: it
|
||||||
does not necessarily rely on operating system specific IO calls, and can be
|
does not necessarily rely on operating system specific IO calls, and can be
|
||||||
easily integrated into any kind of event loop. If you want to implement the AMQP
|
easily integrated into any kind of event loop. If you want to implement the AMQP
|
||||||
protocol on top of some [unusual other communication layer](https://tools.ietf.org/html/rfc1149),
|
protocol on top of some [unusual other communication layer](https://tools.ietf.org/html/rfc1149),
|
||||||
this library can be used for that - but if you want to use it with regular TCP
|
this library can be used for that - but if you want to use it with regular TCP
|
||||||
connections, setting it up is just as easy.
|
connections, setting it up is just as easy.
|
||||||
|
|
||||||
AMQP-CPP is fully asynchronous and does not do any blocking (system) calls, so
|
AMQP-CPP is fully asynchronous and does not do any blocking (system) calls, so
|
||||||
it can be used in high performance applications without the need for threads.
|
it can be used in high performance applications without the need for threads.
|
||||||
|
|
||||||
The AMQP-CPP library uses C++11 features, so if you intend use it, please make
|
The AMQP-CPP library uses C++11 features, so if you intend use it, please make
|
||||||
sure that your compiler is up-to-date and supports C++11.
|
sure that your compiler is up-to-date and supports C++11.
|
||||||
|
|
||||||
**Note for the reader:** This readme file has a peculiar structure. We start
|
**Note for the reader:** This readme file has a peculiar structure. We start
|
||||||
explaining the pure and hard core low level interface in which you have to
|
explaining the pure and hard core low level interface in which you have to
|
||||||
take care of opening socket connections yourself. In reality, you probably want
|
take care of opening socket connections yourself. In reality, you probably want
|
||||||
to use the simpler TCP interface that is being described [later on](#tcp-connections).
|
to use the simpler TCP interface that is being described [later on](#tcp-connections).
|
||||||
|
|
@ -45,13 +45,13 @@ ABOUT
|
||||||
=====
|
=====
|
||||||
|
|
||||||
This library is created and maintained by Copernica (www.copernica.com), and is
|
This library is created and maintained by Copernica (www.copernica.com), and is
|
||||||
used inside the MailerQ (www.mailerq.com), Yothalot (www.yothalot.com) and
|
used inside the MailerQ (www.mailerq.com), Yothalot (www.yothalot.com) and
|
||||||
AMQPipe (www.amqpipe.com) applications. MailerQ is a tool for sending large
|
AMQPipe (www.amqpipe.com) applications. MailerQ is a tool for sending large
|
||||||
volumes of email, using AMQP message queues, Yothalot is a big data processing
|
volumes of email, using AMQP message queues, Yothalot is a big data processing
|
||||||
map/reduce framework and AMQPipe is a tool for high-speed processing messages
|
map/reduce framework and AMQPipe is a tool for high-speed processing messages
|
||||||
between AMQP pipes
|
between AMQP pipes
|
||||||
|
|
||||||
Do you appreciate our work and are you looking for high quality email solutions?
|
Do you appreciate our work and are you looking for high quality email solutions?
|
||||||
Then check out our other commercial and open source solutions:
|
Then check out our other commercial and open source solutions:
|
||||||
|
|
||||||
* Copernica Marketing Suite (www.copernica.com)
|
* Copernica Marketing Suite (www.copernica.com)
|
||||||
|
|
@ -66,24 +66,41 @@ Then check out our other commercial and open source solutions:
|
||||||
|
|
||||||
INSTALLING
|
INSTALLING
|
||||||
==========
|
==========
|
||||||
|
AMQP-CPP comes with an optional Linux-only TCP module that takes care of the network part required for the AMQP-CPP core library.
|
||||||
|
|
||||||
If you are on some kind of Linux environment, installing the library is as easy
|
There are two methods to compile AMQP-CPP: CMake and Make. CMake is platform portable, but the Makefile only works on Linux. After building there are two relevant files to include when using the library.
|
||||||
|
|
||||||
|
File|Include when?
|
||||||
|
----|------------
|
||||||
|
amqpcpp.h|Always
|
||||||
|
amqpcpp/linux_tcp.h|If using the Linux-only TCP module
|
||||||
|
|
||||||
|
## CMake
|
||||||
|
The CMake file supports both building and installing. You can choose not to use the install functionality, and instead manually use the build output at `bin/`. Keep in mind that the TCP module is only supported for Linux. An example install method would be:
|
||||||
|
``` bash
|
||||||
|
mkdir build
|
||||||
|
cd build
|
||||||
|
cmake .. [-DBUILD_SHARED] [-DLINUX_TCP]
|
||||||
|
cmake --build .. --target install
|
||||||
|
```
|
||||||
|
|
||||||
|
Option|Default|Meaning
|
||||||
|
------|-------|-------
|
||||||
|
BUILD_SHARED|OFF|Static lib(ON) or shared lib(OFF)?
|
||||||
|
LINUX_TCP|OFF|Should the Linux-only TCP module be built?
|
||||||
|
|
||||||
|
## Make
|
||||||
|
Installing the library is as easy
|
||||||
as running `make` and `make install`. This will install the full version of
|
as running `make` and `make install`. This will install the full version of
|
||||||
the AMQP-CPP, including the system specific TCP module. If you do not need the
|
the AMQP-CPP, including the system specific TCP module. If you do not need the
|
||||||
additional TCP module (because you take care of handling the network stuff
|
additional TCP module (because you take care of handling the network stuff
|
||||||
yourself), you can also compile a pure form of the library. Use `make pure`
|
yourself), you can also compile a pure form of the library. Use `make pure`
|
||||||
and `make install` for that.
|
and `make install` for that.
|
||||||
|
|
||||||
For users on a non-Linux environment: this library is known to work on your
|
|
||||||
environment too (after all, it does not do any operating specific system calls),
|
|
||||||
but it might take some extra effort to get your compiler to compile it. Please
|
|
||||||
send in your pull requests once you have it running, so that others can benefit
|
|
||||||
from your experiences.
|
|
||||||
|
|
||||||
When you compile an application that uses the AMQP-CPP library, do not
|
When you compile an application that uses the AMQP-CPP library, do not
|
||||||
forget to link with the library. For gcc and clang the linker flag is -lamqpcpp.
|
forget to link with the library. For gcc and clang the linker flag is -lamqpcpp.
|
||||||
If you use the fullblown version of AMQP-CPP (with the TCP module), you also
|
If you use the fullblown version of AMQP-CPP (with the TCP module), you also
|
||||||
need to pass a -lpthread linker flag, because the TCP module uses a thread
|
need to pass a -lpthread linker flag, because the TCP module uses a thread
|
||||||
for running an asynchronous and non-blocking DNS hostname lookup.
|
for running an asynchronous and non-blocking DNS hostname lookup.
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -91,11 +108,11 @@ HOW TO USE AMQP-CPP
|
||||||
===================
|
===================
|
||||||
|
|
||||||
As we mentioned above, the library can be used in a network-agnostic fashion.
|
As we mentioned above, the library can be used in a network-agnostic fashion.
|
||||||
It then does not do any IO by itself, and you need to pass an object to the
|
It then does not do any IO by itself, and you need to pass an object to the
|
||||||
library that the library can use for IO. So, before you start using the
|
library that the library can use for IO. So, before you start using the
|
||||||
library, you first you need to create a class that extends from the
|
library, you first you need to create a class that extends from the
|
||||||
ConnectionHandler base class. This is a class with a number of methods that are
|
ConnectionHandler base class. This is a class with a number of methods that are
|
||||||
called by the library every time it wants to send out data, or when it needs to
|
called by the library every time it wants to send out data, or when it needs to
|
||||||
inform you that an error occured.
|
inform you that an error occured.
|
||||||
|
|
||||||
````c++
|
````c++
|
||||||
|
|
@ -208,16 +225,16 @@ example call the "send()" or "write()" system call to send out the data to
|
||||||
the RabbitMQ server. But what about data in the other direction? How does the
|
the RabbitMQ server. But what about data in the other direction? How does the
|
||||||
library receive data back from RabbitMQ?
|
library receive data back from RabbitMQ?
|
||||||
|
|
||||||
In this raw setup, the AMQP-CPP library does not do any IO by itself and it is
|
In this raw setup, the AMQP-CPP library does not do any IO by itself and it is
|
||||||
therefore also not possible for the library to receive data from a
|
therefore also not possible for the library to receive data from a
|
||||||
socket. It is again up to you to do this. If, for example, you notice in your
|
socket. It is again up to you to do this. If, for example, you notice in your
|
||||||
event loop that the socket that is connected with the RabbitMQ server becomes
|
event loop that the socket that is connected with the RabbitMQ server becomes
|
||||||
readable, you should read out that socket (for example by using the recv() system
|
readable, you should read out that socket (for example by using the recv() system
|
||||||
call), and pass the received bytes to the AMQP-CPP library. This is done by
|
call), and pass the received bytes to the AMQP-CPP library. This is done by
|
||||||
calling the parse() method in the Connection object.
|
calling the parse() method in the Connection object.
|
||||||
|
|
||||||
The Connection::parse() method gets two parameters, a pointer to a buffer of
|
The Connection::parse() method gets two parameters, a pointer to a buffer of
|
||||||
data that you just read from the socket, and a parameter that holds the size of
|
data that you just read from the socket, and a parameter that holds the size of
|
||||||
this buffer. The code snippet below comes from the Connection.h C++ header file.
|
this buffer. The code snippet below comes from the Connection.h C++ header file.
|
||||||
|
|
||||||
````c++
|
````c++
|
||||||
|
|
@ -253,9 +270,9 @@ both the old data, and the new data.
|
||||||
To optimize your calls to the parse() method, you _could_ use the Connection::expected()
|
To optimize your calls to the parse() method, you _could_ use the Connection::expected()
|
||||||
and Connection::maxFrame() methods. The expected() method returns the number of bytes
|
and Connection::maxFrame() methods. The expected() method returns the number of bytes
|
||||||
that the library prefers to receive next. It is pointless to call the parse() method
|
that the library prefers to receive next. It is pointless to call the parse() method
|
||||||
with a smaller buffer, and it is best to call the method with a buffer of exactly this
|
with a smaller buffer, and it is best to call the method with a buffer of exactly this
|
||||||
size. The maxFrame() returns the max frame size for AMQP messages. If you read your
|
size. The maxFrame() returns the max frame size for AMQP messages. If you read your
|
||||||
messages into a reusable buffer, you could allocate this buffer up to this size, so that
|
messages into a reusable buffer, you could allocate this buffer up to this size, so that
|
||||||
you never will have to reallocate.
|
you never will have to reallocate.
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -263,17 +280,17 @@ TCP CONNECTIONS
|
||||||
===============
|
===============
|
||||||
|
|
||||||
Although the AMQP-CPP library gives you extreme flexibility by letting you setup
|
Although the AMQP-CPP library gives you extreme flexibility by letting you setup
|
||||||
your own network connections, the reality is that most if not all AMQP connections
|
your own network connections, the reality is that most if not all AMQP connections
|
||||||
use the TCP protocol. To help you out, the library therefore also comes with a
|
use the TCP protocol. To help you out, the library therefore also comes with a
|
||||||
TCP module that takes care of setting up the network connections, and sending
|
TCP module that takes care of setting up the network connections, and sending
|
||||||
and receiving the data.
|
and receiving the data.
|
||||||
|
|
||||||
If you want to use this TCP module, you should not use the AMQP::Connection
|
If you want to use this TCP module, you should not use the AMQP::Connection
|
||||||
and AMQP::Channel classes that you saw above, but the alternative AMQP::TcpConnection
|
and AMQP::Channel classes that you saw above, but the alternative AMQP::TcpConnection
|
||||||
and AMQP::TcpChannel classes instead. You also do not have to create your own class
|
and AMQP::TcpChannel classes instead. You also do not have to create your own class
|
||||||
that implements the "AMQP::ConnectionHandler" interface - but a class that inherits
|
that implements the "AMQP::ConnectionHandler" interface - but a class that inherits
|
||||||
from "AMQP::TcpHandler" instead. You especially need to implement the "monitor()"
|
from "AMQP::TcpHandler" instead. You especially need to implement the "monitor()"
|
||||||
method in that class, as that is needed by the AMQP-CPP library to interact with
|
method in that class, as that is needed by the AMQP-CPP library to interact with
|
||||||
the main event loop:
|
the main event loop:
|
||||||
|
|
||||||
````c++
|
````c++
|
||||||
|
|
@ -338,7 +355,7 @@ class MyTcpHandler : public AMQP::TcpHandler
|
||||||
// descriptor to the main application event loop (like the select() or
|
// descriptor to the main application event loop (like the select() or
|
||||||
// poll() loop). When the event loop reports that the descriptor becomes
|
// poll() loop). When the event loop reports that the descriptor becomes
|
||||||
// readable and/or writable, it is up to you to inform the AMQP-CPP
|
// readable and/or writable, it is up to you to inform the AMQP-CPP
|
||||||
// library that the filedescriptor is active by calling the
|
// library that the filedescriptor is active by calling the
|
||||||
// connection->process(fd, flags) method.
|
// connection->process(fd, flags) method.
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -348,8 +365,8 @@ The "monitor()" method can be used to integrate the AMQP filedescriptors in your
|
||||||
application's event loop. For some popular event loops (libev, libevent), we have
|
application's event loop. For some popular event loops (libev, libevent), we have
|
||||||
already added example handler objects (see the next section for that).
|
already added example handler objects (see the next section for that).
|
||||||
|
|
||||||
Using the TCP module of the AMQP-CPP library is easier than using the
|
Using the TCP module of the AMQP-CPP library is easier than using the
|
||||||
raw AMQP::Connection and AMQP::Channel objects, because you do not have to
|
raw AMQP::Connection and AMQP::Channel objects, because you do not have to
|
||||||
create the sockets and connections yourself, and you also do not have to take
|
create the sockets and connections yourself, and you also do not have to take
|
||||||
care of buffering network data.
|
care of buffering network data.
|
||||||
|
|
||||||
|
|
@ -380,9 +397,9 @@ EXISTING EVENT LOOPS
|
||||||
|
|
||||||
Both the pure AMQP::Connection as well as the easier AMQP::TcpConnection class
|
Both the pure AMQP::Connection as well as the easier AMQP::TcpConnection class
|
||||||
allow you to integrate AMQP-CPP in your own event loop. Whether you take care
|
allow you to integrate AMQP-CPP in your own event loop. Whether you take care
|
||||||
of running the event loop yourself (for example by using the select() system
|
of running the event loop yourself (for example by using the select() system
|
||||||
call), or if you use an existing library for it (like libevent, libev or libuv),
|
call), or if you use an existing library for it (like libevent, libev or libuv),
|
||||||
you can implement the "monitor()" method to watch the file descriptors and
|
you can implement the "monitor()" method to watch the file descriptors and
|
||||||
hand over control back to AMQP-CPP when one of the sockets become active.
|
hand over control back to AMQP-CPP when one of the sockets become active.
|
||||||
|
|
||||||
For libev and libevent users, we have even implemented an example implementation,
|
For libev and libevent users, we have even implemented an example implementation,
|
||||||
|
|
@ -398,26 +415,26 @@ int main()
|
||||||
{
|
{
|
||||||
// access to the event loop
|
// access to the event loop
|
||||||
auto *loop = EV_DEFAULT;
|
auto *loop = EV_DEFAULT;
|
||||||
|
|
||||||
// handler for libev (so we don't have to implement AMQP::TcpHandler!)
|
// handler for libev (so we don't have to implement AMQP::TcpHandler!)
|
||||||
AMQP::LibEvHandler handler(loop);
|
AMQP::LibEvHandler handler(loop);
|
||||||
|
|
||||||
// make a connection
|
// make a connection
|
||||||
AMQP::TcpConnection connection(&handler, AMQP::Address("amqp://localhost/"));
|
AMQP::TcpConnection connection(&handler, AMQP::Address("amqp://localhost/"));
|
||||||
|
|
||||||
// we need a channel too
|
// we need a channel too
|
||||||
AMQP::TcpChannel channel(&connection);
|
AMQP::TcpChannel channel(&connection);
|
||||||
|
|
||||||
// create a temporary queue
|
// create a temporary queue
|
||||||
channel.declareQueue(AMQP::exclusive).onSuccess([&connection](const std::string &name, uint32_t messagecount, uint32_t consumercount) {
|
channel.declareQueue(AMQP::exclusive).onSuccess([&connection](const std::string &name, uint32_t messagecount, uint32_t consumercount) {
|
||||||
|
|
||||||
// report the name of the temporary queue
|
// report the name of the temporary queue
|
||||||
std::cout << "declared queue " << name << std::endl;
|
std::cout << "declared queue " << name << std::endl;
|
||||||
|
|
||||||
// now we can close the connection
|
// now we can close the connection
|
||||||
connection.close();
|
connection.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
// run the loop
|
// run the loop
|
||||||
ev_run(loop, 0);
|
ev_run(loop, 0);
|
||||||
|
|
||||||
|
|
@ -430,7 +447,7 @@ The AMQP::LibEvHandler and AMQP::LibEventHandler classes are extended AMQP::TcpH
|
||||||
classes, with an implementation of the monitor() method that simply adds the
|
classes, with an implementation of the monitor() method that simply adds the
|
||||||
filedescriptor to the event loop. If you use this class however, it is recommended not to
|
filedescriptor to the event loop. If you use this class however, it is recommended not to
|
||||||
instantiate it directly (like we did in the example), but to create your own
|
instantiate it directly (like we did in the example), but to create your own
|
||||||
"MyHandler" class that extends from it, and in which you also implement the
|
"MyHandler" class that extends from it, and in which you also implement the
|
||||||
onError() method to report possible connection errors to your end users.
|
onError() method to report possible connection errors to your end users.
|
||||||
|
|
||||||
Currently, we have example TcpHandler implementations for libev,
|
Currently, we have example TcpHandler implementations for libev,
|
||||||
|
|
@ -447,15 +464,15 @@ such examples.
|
||||||
HEARTBEATS
|
HEARTBEATS
|
||||||
==========
|
==========
|
||||||
|
|
||||||
The AMQP protocol supports *heartbeats*. If this heartbeat feature is enabled, the
|
The AMQP protocol supports *heartbeats*. If this heartbeat feature is enabled, the
|
||||||
client and the server negotiate a heartbeat interval during connection setup, and
|
client and the server negotiate a heartbeat interval during connection setup, and
|
||||||
they agree to send at least *some kind of data* over the connection during every
|
they agree to send at least *some kind of data* over the connection during every
|
||||||
iteration of that interval. The normal data that is sent over the connection (like
|
iteration of that interval. The normal data that is sent over the connection (like
|
||||||
publishing or consuming messages) is normally sufficient to keep the connection alive,
|
publishing or consuming messages) is normally sufficient to keep the connection alive,
|
||||||
but if the client or server was idle during the negotiated interval time, a dummy
|
but if the client or server was idle during the negotiated interval time, a dummy
|
||||||
heartbeat message must be sent instead.
|
heartbeat message must be sent instead.
|
||||||
|
|
||||||
The default behavior of the AMQP-CPP library is to disable heartbeats. The
|
The default behavior of the AMQP-CPP library is to disable heartbeats. The
|
||||||
proposed heartbeat interval of the server during connection setup (the server
|
proposed heartbeat interval of the server during connection setup (the server
|
||||||
normally suggests an interval of 60 seconds) is vetoed by the AMQP-CPP library so
|
normally suggests an interval of 60 seconds) is vetoed by the AMQP-CPP library so
|
||||||
no heartbeats are ever needed to be sent over the connection. This means that you
|
no heartbeats are ever needed to be sent over the connection. This means that you
|
||||||
|
|
@ -464,7 +481,7 @@ lasting algorithms after you've consumed a message from RabbitMQ, without having
|
||||||
to worry about the connection being idle for too long.
|
to worry about the connection being idle for too long.
|
||||||
|
|
||||||
You can however choose to enable these heartbeats. If you want to enable heartbeats,
|
You can however choose to enable these heartbeats. If you want to enable heartbeats,
|
||||||
simple implement the onNegotiate() method inside your ConnectionHandler or
|
simple implement the onNegotiate() method inside your ConnectionHandler or
|
||||||
TcpHandler class and have it return the interval that you find appropriate.
|
TcpHandler class and have it return the interval that you find appropriate.
|
||||||
|
|
||||||
````c++
|
````c++
|
||||||
|
|
@ -482,14 +499,14 @@ class MyTcpHandler : public AMQP::TcpHandler
|
||||||
*/
|
*/
|
||||||
virtual void onNegotiate(AMQP::TcpConnection *connection, uint16_t interval)
|
virtual void onNegotiate(AMQP::TcpConnection *connection, uint16_t interval)
|
||||||
{
|
{
|
||||||
// we accept the suggestion from the server, but if the interval is smaller
|
// we accept the suggestion from the server, but if the interval is smaller
|
||||||
// that one minute, we will use a one minute interval instead
|
// that one minute, we will use a one minute interval instead
|
||||||
if (interval < 60) interval = 60;
|
if (interval < 60) interval = 60;
|
||||||
|
|
||||||
// @todo
|
// @todo
|
||||||
// set a timer in your event loop, and make sure that you call
|
// set a timer in your event loop, and make sure that you call
|
||||||
// connection->heartbeat() every _interval_ seconds.
|
// connection->heartbeat() every _interval_ seconds.
|
||||||
|
|
||||||
// return the interval that we want to use
|
// return the interval that we want to use
|
||||||
return interval;
|
return interval;
|
||||||
}
|
}
|
||||||
|
|
@ -507,7 +524,7 @@ In the libev event loop implementation the heartbeats are enabled by default.
|
||||||
CHANNELS
|
CHANNELS
|
||||||
========
|
========
|
||||||
|
|
||||||
In the above example we created a channel object. A channel is a sort of virtual
|
In the above example we created a channel object. A channel is a sort of virtual
|
||||||
connection, and it is possible to create many channels that all use
|
connection, and it is possible to create many channels that all use
|
||||||
the same connection.
|
the same connection.
|
||||||
|
|
||||||
|
|
@ -521,8 +538,8 @@ documented.
|
||||||
|
|
||||||
All operations that you can perform on a channel are non-blocking. This means
|
All operations that you can perform on a channel are non-blocking. This means
|
||||||
that it is not possible for a method (like Channel::declareExchange()) to
|
that it is not possible for a method (like Channel::declareExchange()) to
|
||||||
immediately return 'true' or 'false'. Instead, almost every method of the Channel
|
immediately return 'true' or 'false'. Instead, almost every method of the Channel
|
||||||
class returns an instance of the 'Deferred' class. This 'Deferred' object can be
|
class returns an instance of the 'Deferred' class. This 'Deferred' object can be
|
||||||
used to install handlers that will be called in case of success or failure.
|
used to install handlers that will be called in case of success or failure.
|
||||||
|
|
||||||
For example, if you call the channel.declareExchange() method, the AMQP-CPP library
|
For example, if you call the channel.declareExchange() method, the AMQP-CPP library
|
||||||
|
|
@ -614,7 +631,7 @@ channel object right after it was constructed.
|
||||||
CHANNEL ERRORS
|
CHANNEL ERRORS
|
||||||
==============
|
==============
|
||||||
|
|
||||||
It is important to realize that any error that occurs on a channel,
|
It is important to realize that any error that occurs on a channel,
|
||||||
invalidates the entire channel, including all subsequent instructions that
|
invalidates the entire channel, including all subsequent instructions that
|
||||||
were already sent over it. This means that if you call multiple methods in a row,
|
were already sent over it. This means that if you call multiple methods in a row,
|
||||||
and the first method fails, all subsequent methods will not be executed either:
|
and the first method fails, all subsequent methods will not be executed either:
|
||||||
|
|
@ -646,7 +663,7 @@ requires and extra instruction to be sent to the RabbitMQ server, so some extra
|
||||||
bytes are sent over the network, and some additional resources in both the client
|
bytes are sent over the network, and some additional resources in both the client
|
||||||
application and the RabbitMQ server are used (although this is all very limited).
|
application and the RabbitMQ server are used (although this is all very limited).
|
||||||
|
|
||||||
If possible, it is best to make use of this feature. For example, if you have an important AMQP
|
If possible, it is best to make use of this feature. For example, if you have an important AMQP
|
||||||
connection that you use for consuming messages, and at the same time you want
|
connection that you use for consuming messages, and at the same time you want
|
||||||
to send another instruction to RabbitMQ (like declaring a temporary queue), it is
|
to send another instruction to RabbitMQ (like declaring a temporary queue), it is
|
||||||
best to set up a new channel for this 'declare' instruction. If the declare fails,
|
best to set up a new channel for this 'declare' instruction. If the declare fails,
|
||||||
|
|
@ -661,7 +678,7 @@ void myDeclareMethod(AMQP::Connection *connection)
|
||||||
{
|
{
|
||||||
// create temporary channel to declare a queue
|
// create temporary channel to declare a queue
|
||||||
AMQP::Channel channel(connection);
|
AMQP::Channel channel(connection);
|
||||||
|
|
||||||
// declare the queue (the channel object is destructed before the
|
// declare the queue (the channel object is destructed before the
|
||||||
// instruction reaches the server, but the AMQP-CPP library can deal
|
// instruction reaches the server, but the AMQP-CPP library can deal
|
||||||
// with this)
|
// with this)
|
||||||
|
|
@ -844,8 +861,8 @@ channel.commitTransaction()
|
||||||
});
|
});
|
||||||
````
|
````
|
||||||
|
|
||||||
Note that AMQP transactions are not as powerful as transactions that are
|
Note that AMQP transactions are not as powerful as transactions that are
|
||||||
knows in the database world. It is not possible to wrap all sort of
|
knows in the database world. It is not possible to wrap all sort of
|
||||||
operations in a transaction, they are only meaningful for publishing
|
operations in a transaction, they are only meaningful for publishing
|
||||||
and consuming.
|
and consuming.
|
||||||
|
|
||||||
|
|
@ -996,4 +1013,3 @@ class that can be directly plugged into libev, libevent and libuv event loops.
|
||||||
|
|
||||||
For performance reasons, we need to investigate if we can limit the number of times
|
For performance reasons, we need to investigate if we can limit the number of times
|
||||||
an incoming or outgoing messages is copied.
|
an incoming or outgoing messages is copied.
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue