renamed onClosed to onLost to prevent confusion between TcpHandler::onClosed() and ConnectionHandler::onClosed()
This commit is contained in:
parent
b8b332dcec
commit
e83a07f871
151
README.md
151
README.md
|
|
@ -17,9 +17,10 @@ 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 and TLS module that can be used if you trust the AMQP
|
||||||
to take care of the network handling. In that case, the AMQP-CPP library does
|
library to take care of the network (and optional TLS) handling. In that case, the
|
||||||
all the system calls to set up network connections and send and receive the data.
|
AMQP-CPP library does all the system and library calls to set up network connections
|
||||||
|
and send and receive the (possibly encrypted) 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
|
||||||
|
|
@ -68,14 +69,15 @@ network part required for the AMQP-CPP core library. If you use this module, you
|
||||||
are required to link with `pthread` and `dl`.
|
are required to link with `pthread` and `dl`.
|
||||||
|
|
||||||
There are two methods to compile AMQP-CPP: CMake and Make. CMake is platform portable
|
There are two methods to compile AMQP-CPP: CMake and Make. CMake is platform portable
|
||||||
and works on all systems, while the Makefile only works on Linux. Building of a shared
|
and works on all systems, while the Makefile only works on Linux. The two methods
|
||||||
library is currently not supported on Windows.
|
create both a shared and a static version of the AMQP-CPP library. Building of a
|
||||||
|
shared library is currently not supported on Windows.
|
||||||
|
|
||||||
After building there are two relevant files to include when using the library.
|
After building there are two relevant files to #include when you use the library.
|
||||||
|
|
||||||
File | Include when?
|
File | Include when?
|
||||||
---------------------|--------------------------------------------------------
|
---------------------|--------------------------------------------------------
|
||||||
amqpcpp.h | Always
|
amqpcpp.h | Always needed for the core features
|
||||||
amqpcpp/linux_tcp.h | If using the Linux-only TCP module
|
amqpcpp/linux_tcp.h | If using the Linux-only TCP module
|
||||||
|
|
||||||
On Windows you are required to define `NOMINMAX` when compiling code that includes public AMQP-CPP header files.
|
On Windows you are required to define `NOMINMAX` when compiling code that includes public AMQP-CPP header files.
|
||||||
|
|
@ -112,8 +114,8 @@ 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 the -lpthread and -ldl linker flags, because the TCP module uses a
|
need to pass the -lpthread and -ldl linker flags, because the TCP module uses a
|
||||||
thread for running an asynchronous and non-blocking DNS hostname lookup, and it
|
thread for running an asynchronous and non-blocking DNS hostname lookup, and it
|
||||||
may dynamically look up functions from the openssl library if a secure connection
|
must be linked with the "dl" library to allow dynamic lookups for functions from
|
||||||
to RabbitMQ has to be set up.
|
the openssl library if a secure connection to RabbitMQ has to be set up.
|
||||||
|
|
||||||
|
|
||||||
HOW TO USE AMQP-CPP
|
HOW TO USE AMQP-CPP
|
||||||
|
|
@ -122,7 +124,7 @@ 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 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.
|
||||||
|
|
@ -155,7 +157,7 @@ class MyConnectionHandler : public AMQP::ConnectionHandler
|
||||||
* to use.
|
* to use.
|
||||||
* @param connection The connection that can now be used
|
* @param connection The connection that can now be used
|
||||||
*/
|
*/
|
||||||
virtual void onConnected(AMQP::Connection *connection)
|
virtual void onReady(AMQP::Connection *connection)
|
||||||
{
|
{
|
||||||
// @todo
|
// @todo
|
||||||
// add your own implementation, for example by creating a channel
|
// add your own implementation, for example by creating a channel
|
||||||
|
|
@ -180,17 +182,23 @@ class MyConnectionHandler : public AMQP::ConnectionHandler
|
||||||
/**
|
/**
|
||||||
* Method that is called when the connection was closed. This is the
|
* Method that is called when the connection was closed. This is the
|
||||||
* counter part of a call to Connection::close() and it confirms that the
|
* counter part of a call to Connection::close() and it confirms that the
|
||||||
* connection was correctly closed.
|
* AMQP connection was correctly closed.
|
||||||
*
|
*
|
||||||
* @param connection The connection that was closed and that is now unusable
|
* @param connection The connection that was closed and that is now unusable
|
||||||
*/
|
*/
|
||||||
virtual void onClosed(AMQP::Connection *connection) {}
|
virtual void onClosed(AMQP::Connection *connection)
|
||||||
|
{
|
||||||
|
// @todo
|
||||||
|
// add your own implementation, for example by closing down the
|
||||||
|
// underlying TCP connection too
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
````
|
````
|
||||||
After you've implemented the ConnectionHandler class, you can start using
|
After you've implemented the ConnectionHandler class (which is entirely up to
|
||||||
the library by creating a Connection object, and one or more Channel objects:
|
you), you can start using the library by creating a Connection object, and one
|
||||||
|
or more Channel objects:
|
||||||
|
|
||||||
````c++
|
````c++
|
||||||
// create an instance of your own connection handler
|
// create an instance of your own connection handler
|
||||||
|
|
@ -214,13 +222,13 @@ on the heap with the C++ operator 'new'. That works just as well, and is in real
|
||||||
life code probably more useful as you normally want to keep your handlers, connection
|
life code probably more useful as you normally want to keep your handlers, connection
|
||||||
and channel objects around for a longer time.
|
and channel objects around for a longer time.
|
||||||
|
|
||||||
But more importantly, you can see in the example above that we have created the
|
But more importantly, you can see in the example above that we instantiated the
|
||||||
channel object directly after we made the connection object, and we also
|
channel object directly after we made the connection object, and we also
|
||||||
started declaring exchanges and queues right away. However, under the hood, a handshake
|
started declaring exchanges and queues right away. However, under the hood, a handshake
|
||||||
protocol is executed between the server and the client when the Connection
|
protocol is executed between the server and the client when the Connection
|
||||||
object is first created. During this handshake procedure it is not permitted to send
|
object is first created. During this handshake procedure it is not permitted to send
|
||||||
other instructions (like opening a channel or declaring a queue). It would therefore have been better
|
other instructions (like opening a channel or declaring a queue). It would therefore have been better
|
||||||
if we had first waited for the connection to be ready (implement the MyConnectionHandler::onConnected() method),
|
if we had first waited for the connection to be ready (implement the MyConnectionHandler::onReady() method),
|
||||||
and create the channel object only then. But this is not strictly necessary.
|
and create the channel object only then. But this is not strictly necessary.
|
||||||
The methods that are called before the handshake is completed are cached by the
|
The methods that are called before the handshake is completed are cached by the
|
||||||
AMQP library and will be executed the moment the handshake is completed and the
|
AMQP library and will be executed the moment the handshake is completed and the
|
||||||
|
|
@ -301,8 +309,11 @@ 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. This AMQP::TcpHandler class contains a set of
|
||||||
method in that class, as that is needed by the AMQP-CPP library to interact with
|
methods that you can override to intercept all sort of events that occur during the
|
||||||
|
TCP and AMQP connection lifetime. Overriding these methods is mostly optional, because
|
||||||
|
almost all have a default implementation. But you do need to implement the
|
||||||
|
"monitor()" method, as that is needed by the AMQP-CPP library to interact with
|
||||||
the main event loop:
|
the main event loop:
|
||||||
|
|
||||||
````c++
|
````c++
|
||||||
|
|
@ -312,12 +323,56 @@ the main event loop:
|
||||||
class MyTcpHandler : public AMQP::TcpHandler
|
class MyTcpHandler : public AMQP::TcpHandler
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Method that is called by the AMQP library when the login attempt
|
* Method that is called by the AMQP library when a new connection
|
||||||
* succeeded. After this method has been called, the connection is ready
|
* is associated with the handler. This is the first call to your handler
|
||||||
* to use.
|
* @param connection The connection that is attached to the handler
|
||||||
|
*/
|
||||||
|
virtual void onAttached(AMQP::TcpConnection *connection) override {}
|
||||||
|
{
|
||||||
|
// @todo
|
||||||
|
// add your own implementation, for example initialize things
|
||||||
|
// to handle the connection.
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that is called by the AMQP library when the TCP connection
|
||||||
|
* has been established. After this method has been called, the library
|
||||||
|
* still has take care of setting up the optional TLS layer and of
|
||||||
|
* setting up the AMQP connection on top of the TCP layer., This method
|
||||||
|
* is always paired with a later call to onLost().
|
||||||
* @param connection The connection that can now be used
|
* @param connection The connection that can now be used
|
||||||
*/
|
*/
|
||||||
virtual void onConnected(AMQP::TcpConnection *connection)
|
virtual void onConnected(AMQP::TcpConnection *connection) override
|
||||||
|
{
|
||||||
|
// @todo
|
||||||
|
// add your own implementation, for example by creating a channel
|
||||||
|
// instance, and start publishing or consuming
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that is called when the secure TLS connection has been established.
|
||||||
|
* This is only called for amqps:// connections. It allows you to inspect
|
||||||
|
* whether the connection is secure enough for your liking (you can
|
||||||
|
* for example check the server certicate). The AMQP protocol still has
|
||||||
|
* to be started.
|
||||||
|
* @param connection The connection that has been secured
|
||||||
|
* @param ssl SSL structure from openssl library
|
||||||
|
* @return bool True if connection can be used
|
||||||
|
*/
|
||||||
|
virtual bool onSecured(AMQP::TcpConnection *connection, const SSL *ssl) override
|
||||||
|
{
|
||||||
|
// @todo
|
||||||
|
// add your own implementation, for example by reading out the
|
||||||
|
// certificate and check if it is indeed yours
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that is called by the AMQP library when the login attempt
|
||||||
|
* succeeded. After this the connection is ready to use.
|
||||||
|
* @param connection The connection that can now be used
|
||||||
|
*/
|
||||||
|
virtual void onReady(AMQP::TcpConnection *connection) override
|
||||||
{
|
{
|
||||||
// @todo
|
// @todo
|
||||||
// add your own implementation, for example by creating a channel
|
// add your own implementation, for example by creating a channel
|
||||||
|
|
@ -327,26 +382,56 @@ class MyTcpHandler : public AMQP::TcpHandler
|
||||||
/**
|
/**
|
||||||
* Method that is called by the AMQP library when a fatal error occurs
|
* Method that is called by the AMQP library when a fatal error occurs
|
||||||
* on the connection, for example because data received from RabbitMQ
|
* on the connection, for example because data received from RabbitMQ
|
||||||
* could not be recognized.
|
* could not be recognized, or the underlying connection is lost. This
|
||||||
|
* call is normally followed by a call to onLost() (if the error occured
|
||||||
|
* after the TCP connection was established) and onDetached().
|
||||||
* @param connection The connection on which the error occured
|
* @param connection The connection on which the error occured
|
||||||
* @param message A human readable error message
|
* @param message A human readable error message
|
||||||
*/
|
*/
|
||||||
virtual void onError(AMQP::TcpConnection *connection, const char *message)
|
virtual void onError(AMQP::TcpConnection *connection, const char *message) override
|
||||||
{
|
{
|
||||||
// @todo
|
// @todo
|
||||||
// add your own implementation, for example by reporting the error
|
// add your own implementation, for example by reporting the error
|
||||||
// to the user of your program, log the error, and destruct the
|
// to the user of your program and logging the error
|
||||||
// connection object because it is no longer in a usable state
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method that is called when the connection was closed. This is the
|
* Method that is called when the AMQP protocol is ended. This is the
|
||||||
* counter part of a call to Connection::close() and it confirms that the
|
* counter-part of a call to connection.close() to graceful shutdown
|
||||||
* connection was correctly closed.
|
* the connection. Note that the TCP connection is at this time still
|
||||||
*
|
* active, and you will also receive calls to onLost() and onDetached()
|
||||||
|
* @param connection The connection over which the AMQP protocol ended
|
||||||
|
*/
|
||||||
|
virtual void onClosed(AMQP::TcpConnection *connection) override
|
||||||
|
{
|
||||||
|
// @todo
|
||||||
|
// add your own implementation (probably not necessary, but it could
|
||||||
|
// be useful if you want to do some something immediately after the
|
||||||
|
// amqp connection is over, but do not want to wait for the tcp
|
||||||
|
// connection to shut down
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that is called when the TCP connection was closed or lost.
|
||||||
|
* This method is always called if there was also a call to onConnected()
|
||||||
* @param connection The connection that was closed and that is now unusable
|
* @param connection The connection that was closed and that is now unusable
|
||||||
*/
|
*/
|
||||||
virtual void onClosed(AMQP::TcpConnection *connection) {}
|
virtual void onLost(AMQP::TcpConnection *connection) override
|
||||||
|
{
|
||||||
|
// @todo
|
||||||
|
// add your own implementation (probably not necessary)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Final method that is called. This signals that no further calls to your
|
||||||
|
* handler will be made about the connection.
|
||||||
|
* @param connection The connection that can be destructed
|
||||||
|
*/
|
||||||
|
virtual void onDetached(AMQP::TcpConnection *connection) override
|
||||||
|
{
|
||||||
|
// @todo
|
||||||
|
// add your own implementation, like cleanup resources or exit the application
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method that is called by the AMQP-CPP library when it wants to interact
|
* Method that is called by the AMQP-CPP library when it wants to interact
|
||||||
|
|
@ -361,7 +446,7 @@ class MyTcpHandler : public AMQP::TcpHandler
|
||||||
* @param fd The filedescriptor that should be checked
|
* @param fd The filedescriptor that should be checked
|
||||||
* @param flags Bitwise or of AMQP::readable and/or AMQP::writable
|
* @param flags Bitwise or of AMQP::readable and/or AMQP::writable
|
||||||
*/
|
*/
|
||||||
virtual void monitor(AMQP::TcpConnection *connection, int fd, int flags)
|
virtual void monitor(AMQP::TcpConnection *connection, int fd, int flags) override
|
||||||
{
|
{
|
||||||
// @todo
|
// @todo
|
||||||
// add your own implementation, for example by adding the file
|
// add your own implementation, for example by adding the file
|
||||||
|
|
|
||||||
|
|
@ -172,10 +172,10 @@ private:
|
||||||
virtual void onError(TcpState *state, const char *message, bool connected) override;
|
virtual void onError(TcpState *state, const char *message, bool connected) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method to be called when it is detected that the connection was closed
|
* Method to be called when it is detected that the connection was lost
|
||||||
* @param state
|
* @param state
|
||||||
*/
|
*/
|
||||||
virtual void onClosed(TcpState *state) override;
|
virtual void onLost(TcpState *state) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The expected number of bytes
|
* The expected number of bytes
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ public:
|
||||||
* Method that is called when the TCP connection ends up in a connected state
|
* Method that is called when the TCP connection ends up in a connected state
|
||||||
* This method is called after the TCP connection has been set up, but before
|
* This method is called after the TCP connection has been set up, but before
|
||||||
* the (optional) secure TLS connection is ready, and before the AMQP login
|
* the (optional) secure TLS connection is ready, and before the AMQP login
|
||||||
* handshake has been completed. If this step has been set, the onClosed()
|
* handshake has been completed. If this step has been set, the onLost()
|
||||||
* method will also always be called when the connection is closed.
|
* method will also always be called when the connection is closed.
|
||||||
* @param connection The TCP connection
|
* @param connection The TCP connection
|
||||||
*/
|
*/
|
||||||
|
|
@ -148,7 +148,7 @@ public:
|
||||||
* This could either be an error at the AMQP level, but could also
|
* This could either be an error at the AMQP level, but could also
|
||||||
* be an error at the TCP of SSL level (like a broken connection).
|
* be an error at the TCP of SSL level (like a broken connection).
|
||||||
* If the connection is connected (the onConnected() method was called
|
* If the connection is connected (the onConnected() method was called
|
||||||
* before), the onClosed() method is going to be called too.
|
* before), the onLost() method is going to be called too.
|
||||||
* @param connection The TCP connection
|
* @param connection The TCP connection
|
||||||
* @param message Error message
|
* @param message Error message
|
||||||
*/
|
*/
|
||||||
|
|
@ -158,10 +158,12 @@ public:
|
||||||
(void) connection;
|
(void) connection;
|
||||||
(void) message;
|
(void) message;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method that is called when the TCP connection is closed. This method
|
* Method that is called when the AMQP protocol was gracefully ended.
|
||||||
* is always called if you have also received a call to onConnected().
|
* This is the counter-part of a call to connection.close(). Note that
|
||||||
|
* the underlying TCP connection is still alive, and onLost() and
|
||||||
|
* onDetached() (see below) are going to be called too.
|
||||||
* @param connection The TCP connection
|
* @param connection The TCP connection
|
||||||
*/
|
*/
|
||||||
virtual void onClosed(TcpConnection *connection)
|
virtual void onClosed(TcpConnection *connection)
|
||||||
|
|
@ -169,6 +171,17 @@ public:
|
||||||
// make sure compilers dont complain about unused parameters
|
// make sure compilers dont complain about unused parameters
|
||||||
(void) connection;
|
(void) connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that is called when the TCP connection is lost or closed. This
|
||||||
|
* is always called if you have also received a call to onConnected().
|
||||||
|
* @param connection The TCP connection
|
||||||
|
*/
|
||||||
|
virtual void onLost(TcpConnection *connection)
|
||||||
|
{
|
||||||
|
// make sure compilers dont complain about unused parameters
|
||||||
|
(void) connection;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method that is called when the handler will no longer be notified.
|
* Method that is called when the handler will no longer be notified.
|
||||||
|
|
|
||||||
|
|
@ -80,10 +80,10 @@ public:
|
||||||
virtual void onError(TcpState *state, const char *message, bool connected = true) = 0;
|
virtual void onError(TcpState *state, const char *message, bool connected = true) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method to be called when it is detected that the connection was nicely closed
|
* Method to be called when it is detected that the connection was lost
|
||||||
* @param state
|
* @param state
|
||||||
*/
|
*/
|
||||||
virtual void onClosed(TcpState *state) = 0;
|
virtual void onLost(TcpState *state) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The expected number of bytes
|
* The expected number of bytes
|
||||||
|
|
|
||||||
|
|
@ -186,6 +186,9 @@ void TcpConnection::onClosed(Connection *connection)
|
||||||
{
|
{
|
||||||
// tell the state that the connection should be closed asap
|
// tell the state that the connection should be closed asap
|
||||||
_state->close();
|
_state->close();
|
||||||
|
|
||||||
|
// report to the handler
|
||||||
|
_handler->onClosed(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -215,16 +218,16 @@ void TcpConnection::onError(TcpState *state, const char *message, bool connected
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method to be called when it is detected that the connection was closed
|
* Method to be called when it is detected that the connection was lost
|
||||||
* @param state
|
* @param state
|
||||||
*/
|
*/
|
||||||
void TcpConnection::onClosed(TcpState *state)
|
void TcpConnection::onLost(TcpState *state)
|
||||||
{
|
{
|
||||||
// monitor to check if "this" is destructed
|
// monitor to check if "this" is destructed
|
||||||
Monitor monitor(this);
|
Monitor monitor(this);
|
||||||
|
|
||||||
// tell the handler
|
// tell the handler
|
||||||
_handler->onClosed(this);
|
_handler->onLost(this);
|
||||||
|
|
||||||
// leap out if object was destructed
|
// leap out if object was destructed
|
||||||
if (!monitor.valid()) return;
|
if (!monitor.valid()) return;
|
||||||
|
|
|
||||||
|
|
@ -46,8 +46,8 @@ protected:
|
||||||
// forget the socket
|
// forget the socket
|
||||||
_socket = -1;
|
_socket = -1;
|
||||||
|
|
||||||
// tell the handler that the connection is now closed
|
// tell the handler that the connection is now lost
|
||||||
_parent->onClosed(this);
|
_parent->onLost(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue