updated Makefile, removed vhost from Login object, now also the commit of the README file and the header files

This commit is contained in:
Emiel Bruijntjes 2014-01-04 05:11:06 -08:00
parent c87739312a
commit 7a6527dddf
9 changed files with 118 additions and 71 deletions

View File

@ -74,4 +74,71 @@ class MyConnectionHandler : public AMQP::ConnectionHandler
}
};
````
After you've implemented the ConnectionHandler class, you can start using
the library by creating a Connection object, and one or more Channel objects:
````c++
// create an instance of your own connection handler
MyConnectionHandler myHandler;
// create a AMQP connection object
AMQP::Connection connection(&myHandler, Login("guest","guest"), "/");
// and create a channel
AMQP::Channel channel(&connection);
// use the channel object to call the AMQP method you like
channel.declareExchange("my-exchange", AMQP::fanout);
channel.declareQueue("my-queue");
channel.bindQueue("my-exchange", "my-queue");
````
A number of remarks about the above example. First you may have noticed that we've
created all objects on the stack. You are of course also free to create them
on the heap with the C++ operator 'new'. That works just as good.
But more importantly, you see that in the example above we have created the
channel object directly after we created the connection object, and we did also
start declaring exchanges and queues right away. It would have been better to
first wait for the connection to be ready (and the onConnected() method is called
in your handler object), before you create channel objects and start calling
methods. But if you insist, you do not have to wait, and you are free to call
the additional methods right away.
As we've explained above, the AMQP library does not do any IO by itself and when it
needs to send data to RabbitMQ, it will call the onData() method in your handler
object. But it is of course also not possible for the library to receive data from
the server. It is again up to you to to this. If, for example, you notice in your
event loop that the socket that is connected with the RabbitMQ server becomes
readable, you should read out that data (for example by calling the recv() system
call), and pass the received bytes to the AMQP library. This can be done by
calling the parse() method in the Connection object.
The Connection::parse() method gets two parameters, a pointer to a buffer of
data received from RabbitMQ, and a parameter that holds the size of this buffer.
The code snippet below comes from the Connection.h C++ header file.
````c++
/**
* Parse data that was recevied from RabbitMQ
*
* Every time that data comes in from RabbitMQ, you should call this method to parse
* the incoming data, and let it handle by the AMQP library. This method returns the number
* of bytes that were processed.
*
* If not all bytes could be processed because it only contained a partial frame, you should
* call this same method later on when more data is available. The AMQP library does not do
* any buffering, so it is up to the caller to ensure that the old data is also passed in that
* later call.
*
* @param buffer buffer to decode
* @param size size of the buffer to decode
* @return number of bytes that were processed
*/
size_t parse(char *buffer, size_t size)
{
return _implementation.parse(buffer, size);
}
````

View File

@ -33,7 +33,7 @@ public:
* @param channel
* @param message
*/
virtual void onChannelError(Channel *channel, const std::string &message) {}
virtual void onError(Channel *channel, const std::string &message) {}
/**
* Method that is called when the channel was paused

View File

@ -281,7 +281,7 @@ public:
_state = state_closed;
// inform handler
if (_handler) _handler->onChannelError(_parent, message);
if (_handler) _handler->onError(_parent, message);
}
/**

View File

@ -30,14 +30,28 @@ public:
*
* @param handler Connection handler
* @param login Login data
* @param vhost Vhost to use
*/
Connection(ConnectionHandler *handler, const Login &login) : _implementation(this, handler, login) {}
Connection(ConnectionHandler *handler, const Login &login, const std::string &vhost) : _implementation(this, handler, login, vhost) {}
/**
* Construct an AMQP object with default login data
* Construct with default vhost
* @param handler Connection handler
* @param login Login data
*/
Connection(ConnectionHandler *handler, const Login &login) : _implementation(this, handler, login, "/") {}
/**
* Construct an AMQP object with default login data and default vhost
* @param handler Connection handler
*/
Connection(ConnectionHandler *handler) : _implementation(this, handler) {}
Connection(ConnectionHandler *handler, const std::string &vhost) : _implementation(this, handler, Login(), vhost) {}
/**
* Construct an AMQP object with default login data and default vhost
* @param handler Connection handler
*/
Connection(ConnectionHandler *handler) : _implementation(this, handler, Login(), "/") {}
/**
* Destructor
@ -45,9 +59,9 @@ public:
virtual ~Connection() {}
/**
* Parse the buffer into a recognized frame
* Parse data that was recevied from RabbitMQ
*
* Every time that data comes in on the connection, you should call this method to parse
* Every time that data comes in from RabbitMQ, you should call this method to parse
* the incoming data, and let it handle by the AMQP library. This method returns the number
* of bytes that were processed.
*

View File

@ -38,14 +38,12 @@ public:
* This happens when data comes in that does not match the AMQP protocol
*
* After this method is called, the connection no longer is in a valid
* state and can be used. In normal circumstances this method is not called.
* state and can no longer be used.
*
* @todo do we need this method, or only in the ChannelHandler class?
*
* @param connection The connection that entered the error state
* @param message Error message
*/
virtual void onConnectionError(Connection *connection, const std::string &message) = 0;
virtual void onError(Connection *connection, const std::string &message) = 0;
/**
* Method that is called when the login attempt succeeded. After this method

View File

@ -69,15 +69,17 @@ protected:
uint32_t _maxFrame = 10000;
/**
* The address of the server (vhost, login, password)
* @var Address
* The login for the server (login, password)
* @var Login
*/
Login _login;
/**
* Initialize the connection
* Vhost to connect to
* @var string
*/
void initialize();
std::string _vhost;
private:
/**
@ -93,28 +95,7 @@ private:
* @param handler Connection handler
* @param login Login data
*/
ConnectionImpl(Connection *parent, ConnectionHandler *handler, const Login &login) :
_parent(parent), _handler(handler), _login(login)
{
// initialize the connection
initialize();
}
/**
* Construct an AMQP object with default login data
*
* Note that the constructor is private to ensure that nobody can construct
* this class, only the real Connection class via a friend construct
*
* @param parent Parent connection object
* @param handler Connection handler
*/
ConnectionImpl(Connection *parent, ConnectionHandler *handler) :
_parent(parent), _handler(handler)
{
// initialize the connection
initialize();
}
ConnectionImpl(Connection *parent, ConnectionHandler *handler, const Login &login, const std::string &vhost);
public:
/**
@ -171,6 +152,15 @@ public:
{
return _login;
}
/**
* Retrieve the vhost
* @return string
*/
std::string &vhost()
{
return _vhost;
}
/**
* Store the max number of channels and max number of frames
@ -261,7 +251,7 @@ public:
_state = state_closed;
// inform handler
_handler->onConnectionError(_parent, message);
_handler->onError(_parent, message);
// @Todo: notify all channels of closed connection
}

View File

@ -17,47 +17,34 @@ namespace AMQP {
class Login
{
private:
/**
* The vhost
* @var string
*/
std::string _vhost;
/**
* The username
* @var string
*/
std::string _user;
/**
* The password
* @var string
*/
std::string _password;
public:
/**
* Constructor
* @param vhost
* @param user
* @param password
*/
Login(const std::string &vhost, const std::string &user, const std::string &password) :
_vhost(vhost), _user(user), _password(password) {}
/**
* Constructor
* @param user
* @param password
*/
Login(const std::string &user, const std::string &password) :
_vhost("/"), _user(user), _password(password) {}
_user(user), _password(password) {}
/**
* Constructor
*/
Login() :
_vhost("/"), _user("guest"), _password("guest") {}
_user("guest"), _password("guest") {}
/**
* Destructor
@ -76,15 +63,6 @@ public:
// append other elements
return result.append(_user).append("\0",1).append(_password);
}
/**
* Retrieve the vhost
* @return string
*/
std::string &vhost()
{
return _vhost;
}
};
/**

View File

@ -171,7 +171,7 @@ void MyConnection::onData(AMQP::Connection *connection, const char *buffer, size
* @param connection The connection that entered the error state
* @param message Error message
*/
void MyConnection::onConnectionError(AMQP::Connection *connection, const std::string &message)
void MyConnection::onError(AMQP::Connection *connection, const std::string &message)
{
// report error
std::cout << "AMQP Connection error: " << message << std::endl;
@ -216,7 +216,7 @@ void MyConnection::onReady(AMQP::Channel *channel)
* @param message
*/
void MyConnection::onChannelError(AMQP::Channel *channel, const std::string &message)
void MyConnection::onError(AMQP::Channel *channel, const std::string &message)
{
// show
std::cout << "AMQP channel error, id: " << (int) channel->id() << " - message: " << message << std::endl;

View File

@ -95,7 +95,7 @@ private:
* @param connection The connection that entered the error state
* @param message Error message
*/
virtual void onConnectionError(AMQP::Connection *connection, const std::string &message) override;
virtual void onError(AMQP::Connection *connection, const std::string &message) override;
/**
* Method that is called when the login attempt succeeded. After this method
@ -117,7 +117,7 @@ private:
* @param channel
* @param message
*/
virtual void onChannelError(AMQP::Channel *channel, const std::string &message) override;
virtual void onError(AMQP::Channel *channel, const std::string &message) override;
/**
* Method that is called when the channel was paused