improved the tcp handler, added more methods to monitor whether a connection is connected, logged on and in an error state
This commit is contained in:
parent
bb417e89c2
commit
54049f9e8e
|
|
@ -42,10 +42,8 @@ private:
|
||||||
* The state of the TCP connection - this state objecs changes based on
|
* The state of the TCP connection - this state objecs changes based on
|
||||||
* the state of the connection (resolving, connected or closed)
|
* the state of the connection (resolving, connected or closed)
|
||||||
* @var std::unique_ptr<TcpState>
|
* @var std::unique_ptr<TcpState>
|
||||||
*
|
|
||||||
* @todo why is this a shared pointer?
|
|
||||||
*/
|
*/
|
||||||
std::shared_ptr<TcpState> _state;
|
std::unique_ptr<TcpState> _state;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The underlying AMQP connection
|
* The underlying AMQP connection
|
||||||
|
|
@ -92,10 +90,8 @@ private:
|
||||||
*/
|
*/
|
||||||
virtual void onConnected(Connection *connection) override
|
virtual void onConnected(Connection *connection) override
|
||||||
{
|
{
|
||||||
// @todo we may need this, because from this moment on we can pass an onClosed()
|
|
||||||
|
|
||||||
// pass on to the handler
|
// pass on to the handler
|
||||||
_handler->onConnected(this);
|
_handler->onReady(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -103,6 +99,28 @@ private:
|
||||||
* @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(Connection *connection) override;
|
virtual void onClosed(Connection *connection) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that is called when the tcp connection has been established
|
||||||
|
* @param state
|
||||||
|
*/
|
||||||
|
virtual void onConnected(TcpState *state) override
|
||||||
|
{
|
||||||
|
// pass on to the handler
|
||||||
|
_handler->onConnected(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that is called when the connection is secured
|
||||||
|
* @param state
|
||||||
|
* @param ssl
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
virtual bool onSecured(TcpState *state, const SSL *ssl) override
|
||||||
|
{
|
||||||
|
// pass on to user-space
|
||||||
|
return _handler->onSecured(this, ssl);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method to be called when data was received
|
* Method to be called when data was received
|
||||||
|
|
@ -116,18 +134,6 @@ private:
|
||||||
return _connection.parse(buffer);
|
return _connection.parse(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Method that is called when the connection is secured
|
|
||||||
* @param state
|
|
||||||
* @param ssl
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
virtual bool onSecured(TcpState *state, const SSL *ssl) override
|
|
||||||
{
|
|
||||||
// pass on to user-space
|
|
||||||
return _handler->onSecured(this, ssl);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method to be called when we need to monitor a different filedescriptor
|
* Method to be called when we need to monitor a different filedescriptor
|
||||||
* @param state
|
* @param state
|
||||||
|
|
@ -140,6 +146,14 @@ private:
|
||||||
return _handler->monitor(this, socket, events);
|
return _handler->monitor(this, socket, events);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that is called when an error occurs (the connection is lost)
|
||||||
|
* @param state
|
||||||
|
* @param error
|
||||||
|
* @param connected
|
||||||
|
*/
|
||||||
|
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 closed
|
||||||
* @param state
|
* @param state
|
||||||
|
|
@ -164,6 +178,12 @@ public:
|
||||||
*/
|
*/
|
||||||
TcpConnection(TcpHandler *handler, const Address &address);
|
TcpConnection(TcpHandler *handler, const Address &address);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* No copying
|
||||||
|
* @param that
|
||||||
|
*/
|
||||||
|
TcpConnection(const TcpConnection &that) = delete;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destructor
|
* Destructor
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -38,8 +38,6 @@ public:
|
||||||
/**
|
/**
|
||||||
* Method that is called immediately after a connection has been constructed.
|
* Method that is called immediately after a connection has been constructed.
|
||||||
* @param connection The connection object that was just constructed
|
* @param connection The connection object that was just constructed
|
||||||
*
|
|
||||||
* @see ConnectionHandler::onAttached
|
|
||||||
*/
|
*/
|
||||||
virtual void onAttached(TcpConnection *connection)
|
virtual void onAttached(TcpConnection *connection)
|
||||||
{
|
{
|
||||||
|
|
@ -48,12 +46,14 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method that is called right before a connection object is destructed.
|
* Method that is called when the TCP connection ends up in a connected state
|
||||||
* @param connection The connection that is being destructed
|
* 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
|
||||||
* @see ConnectionHandler::onDetached
|
* handshake has been completed. If this step has been set, the onClosed()
|
||||||
|
* method will also always be called when the connection is closed.
|
||||||
|
* @param connection The TCP connection
|
||||||
*/
|
*/
|
||||||
virtual void onDetached(TcpConnection *connection)
|
virtual void onConnected(TcpConnection *connection)
|
||||||
{
|
{
|
||||||
// make sure compilers dont complain about unused parameters
|
// make sure compilers dont complain about unused parameters
|
||||||
(void) connection;
|
(void) connection;
|
||||||
|
|
@ -107,12 +107,11 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method that is called when the AMQP connection ends up in a connected state
|
* Method that is called after the AMQP login handshake has been completed
|
||||||
* This method is called after the TCP connection has been set up, the (optional)
|
* and the connection object is ready for sending out actual AMQP instructions
|
||||||
* secure TLS connection, and the AMQP login handshake has been completed.
|
|
||||||
* @param connection The TCP connection
|
* @param connection The TCP connection
|
||||||
*/
|
*/
|
||||||
virtual void onConnected(TcpConnection *connection)
|
virtual void onReady(TcpConnection *connection)
|
||||||
{
|
{
|
||||||
// make sure compilers dont complain about unused parameters
|
// make sure compilers dont complain about unused parameters
|
||||||
(void) connection;
|
(void) connection;
|
||||||
|
|
@ -121,7 +120,6 @@ public:
|
||||||
/**
|
/**
|
||||||
* Method that is called when the server sends a heartbeat to the client
|
* Method that is called when the server sends a heartbeat to the client
|
||||||
* @param connection The connection over which the heartbeat was received
|
* @param connection The connection over which the heartbeat was received
|
||||||
*
|
|
||||||
* @see ConnectionHandler::onHeartbeat
|
* @see ConnectionHandler::onHeartbeat
|
||||||
*/
|
*/
|
||||||
virtual void onHeartbeat(TcpConnection *connection)
|
virtual void onHeartbeat(TcpConnection *connection)
|
||||||
|
|
@ -131,7 +129,11 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method that is called when the TCP connection ends up in an error state
|
* Method that is called when the connection ends up in an error state
|
||||||
|
* 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).
|
||||||
|
* If the connection is connected (the onConnected() method was called
|
||||||
|
* before), the onClosed() 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
|
||||||
*/
|
*/
|
||||||
|
|
@ -143,7 +145,8 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method that is called when the TCP connection is closed
|
* Method that is called when the TCP connection is closed. This method
|
||||||
|
* is always called if you have also received a call to onConnected().
|
||||||
* @param connection The TCP connection
|
* @param connection The TCP connection
|
||||||
*/
|
*/
|
||||||
virtual void onClosed(TcpConnection *connection)
|
virtual void onClosed(TcpConnection *connection)
|
||||||
|
|
@ -152,6 +155,18 @@ public:
|
||||||
(void) connection;
|
(void) connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that is called when the handler will no longer be notified.
|
||||||
|
* This is the last call to your handler, and it is typically used
|
||||||
|
* to clean up stuff.
|
||||||
|
* @param connection The connection that is being destructed
|
||||||
|
*/
|
||||||
|
virtual void onDetached(TcpConnection *connection)
|
||||||
|
{
|
||||||
|
// make sure compilers dont complain about unused parameters
|
||||||
|
(void) connection;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Monitor a filedescriptor for readability or writability
|
* Monitor a filedescriptor for readability or writability
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -40,14 +40,13 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual ~TcpParent() = default;
|
virtual ~TcpParent() = default;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method to be called when data was received
|
* Method that is called when the TCP connection has been established
|
||||||
* @param state
|
* @param state
|
||||||
* @param buffer
|
|
||||||
* @return size_t
|
|
||||||
*/
|
*/
|
||||||
virtual size_t onReceived(TcpState *state, const Buffer &buffer) = 0;
|
virtual void onConnected(TcpState *state) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method that is called when the connection is secured
|
* Method that is called when the connection is secured
|
||||||
* @param state
|
* @param state
|
||||||
|
|
@ -55,6 +54,14 @@ public:
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
virtual bool onSecured(TcpState *state, const SSL *ssl) = 0;
|
virtual bool onSecured(TcpState *state, const SSL *ssl) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to be called when data was received
|
||||||
|
* @param state
|
||||||
|
* @param buffer
|
||||||
|
* @return size_t
|
||||||
|
*/
|
||||||
|
virtual size_t onReceived(TcpState *state, const Buffer &buffer) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method to be called when we need to monitor a different filedescriptor
|
* Method to be called when we need to monitor a different filedescriptor
|
||||||
|
|
@ -68,8 +75,9 @@ public:
|
||||||
* Method that is called when an error occurs (the connection is lost)
|
* Method that is called when an error occurs (the connection is lost)
|
||||||
* @param state
|
* @param state
|
||||||
* @param error
|
* @param error
|
||||||
|
* @param connected
|
||||||
*/
|
*/
|
||||||
virtual void onError(TcpState *state, const char *message) = 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 nicely closed
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,11 @@ namespace AMQP {
|
||||||
TcpConnection::TcpConnection(TcpHandler *handler, const Address &address) :
|
TcpConnection::TcpConnection(TcpHandler *handler, const Address &address) :
|
||||||
_handler(handler),
|
_handler(handler),
|
||||||
_state(new TcpResolver(this, address.hostname(), address.port(), address.secure())),
|
_state(new TcpResolver(this, address.hostname(), address.port(), address.secure())),
|
||||||
_connection(this, address.login(), address.vhost()) {}
|
_connection(this, address.login(), address.vhost())
|
||||||
|
{
|
||||||
|
// tell the handler
|
||||||
|
_handler->onAttached(this);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destructor
|
* Destructor
|
||||||
|
|
@ -167,7 +171,7 @@ void TcpConnection::onData(Connection *connection, const char *buffer, size_t si
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method called when the connection ends up in an error state
|
* Method called when the AMQP connection ends up in an error state
|
||||||
* @param connection The connection that entered the error state
|
* @param connection The connection that entered the error state
|
||||||
* @param message Error message
|
* @param message Error message
|
||||||
*/
|
*/
|
||||||
|
|
@ -176,6 +180,9 @@ void TcpConnection::onError(Connection *connection, const char *message)
|
||||||
// monitor to check if "this" is destructed
|
// monitor to check if "this" is destructed
|
||||||
Monitor monitor(this);
|
Monitor monitor(this);
|
||||||
|
|
||||||
|
// tell this to the user
|
||||||
|
_handler->onError(this, message);
|
||||||
|
|
||||||
// remember the old state (this is necessary because _state may be modified by user-code)
|
// remember the old state (this is necessary because _state may be modified by user-code)
|
||||||
auto *oldstate = _state.get();
|
auto *oldstate = _state.get();
|
||||||
|
|
||||||
|
|
@ -211,6 +218,50 @@ void TcpConnection::onClosed(Connection *connection)
|
||||||
_state.reset(newstate);
|
_state.reset(newstate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that is called when an error occurs (the connection is lost)
|
||||||
|
* @param state
|
||||||
|
* @param error
|
||||||
|
* @param connected
|
||||||
|
*/
|
||||||
|
void TcpConnection::onError(TcpState *state, const char *message, bool connected)
|
||||||
|
{
|
||||||
|
// if the object is still connected, we only have to report the error and
|
||||||
|
// we wait for the subsequent call to the onClosed() method
|
||||||
|
if (connected) return _handler->onError(this, message);
|
||||||
|
|
||||||
|
// monitor to check if "this" is destructed
|
||||||
|
Monitor monitor(this);
|
||||||
|
|
||||||
|
// tell the handler
|
||||||
|
_handler->onError(this, message);
|
||||||
|
|
||||||
|
// leap out if object was destructed
|
||||||
|
if (!monitor.valid()) return;
|
||||||
|
|
||||||
|
// tell the handler that no further events will be fired
|
||||||
|
_handler->onDetached(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to be called when it is detected that the connection was closed
|
||||||
|
* @param state
|
||||||
|
*/
|
||||||
|
void TcpConnection::onClosed(TcpState *state)
|
||||||
|
{
|
||||||
|
// monitor to check if "this" is destructed
|
||||||
|
Monitor monitor(this);
|
||||||
|
|
||||||
|
// tell the handler
|
||||||
|
_handler->onClosed(this);
|
||||||
|
|
||||||
|
// leap out if object was destructed
|
||||||
|
if (!monitor.valid()) return;
|
||||||
|
|
||||||
|
// tell the handler that no further events will be fired
|
||||||
|
_handler->onDetached(this);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* End of namespace
|
* End of namespace
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -192,6 +192,12 @@ public:
|
||||||
// do we have a valid socket?
|
// do we have a valid socket?
|
||||||
if (_socket >= 0)
|
if (_socket >= 0)
|
||||||
{
|
{
|
||||||
|
// report that the network-layer is connected
|
||||||
|
_parent->onConnected(this);
|
||||||
|
|
||||||
|
// handler callback might have destroyed connection
|
||||||
|
if (!monitor.valid()) return nullptr;
|
||||||
|
|
||||||
// if we need a secure connection, we move to the tls handshake
|
// if we need a secure connection, we move to the tls handshake
|
||||||
// @todo catch possible exception
|
// @todo catch possible exception
|
||||||
if (_secure) return new SslHandshake(this, _hostname, std::move(_buffer));
|
if (_secure) return new SslHandshake(this, _hostname, std::move(_buffer));
|
||||||
|
|
@ -202,7 +208,7 @@ public:
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// report error
|
// report error
|
||||||
_parent->onError(this, _error.data());
|
_parent->onError(this, _error.data(), false);
|
||||||
|
|
||||||
// handler callback might have destroyed connection
|
// handler callback might have destroyed connection
|
||||||
if (!monitor.valid()) return nullptr;
|
if (!monitor.valid()) return nullptr;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue