2017-08-08 13:53:47 +02:00
|
|
|
#ifndef CONNECTION_H_
|
|
|
|
#define CONNECTION_H_
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
2018-10-24 16:01:30 +02:00
|
|
|
#include <asio.hpp>
|
2017-08-08 13:53:47 +02:00
|
|
|
#include <vector>
|
|
|
|
#include <list>
|
2018-10-24 13:52:27 +02:00
|
|
|
#include <atomic>
|
2017-08-08 13:53:47 +02:00
|
|
|
|
2018-03-06 22:22:19 +01:00
|
|
|
#include "Forwards.h"
|
2017-08-08 13:53:47 +02:00
|
|
|
#include "Acceptor.h"
|
2018-10-24 17:58:57 +02:00
|
|
|
#include <memory>
|
2017-08-08 13:53:47 +02:00
|
|
|
|
2018-12-23 03:53:08 +01:00
|
|
|
namespace Sapphire
|
|
|
|
{
|
|
|
|
class Framework;
|
|
|
|
using FrameworkPtr = std::shared_ptr< Framework >;
|
|
|
|
}
|
|
|
|
|
2018-11-29 16:55:48 +01:00
|
|
|
namespace Sapphire::Network
|
2018-10-28 21:53:21 +01:00
|
|
|
{
|
2018-08-29 21:40:59 +02:00
|
|
|
|
2018-10-28 21:53:21 +01:00
|
|
|
class Hive;
|
|
|
|
class Acceptor;
|
|
|
|
class Connection;
|
2018-08-29 21:40:59 +02:00
|
|
|
|
2018-10-28 21:53:21 +01:00
|
|
|
//-----------------------------------------------------------------------------
|
2018-08-29 21:40:59 +02:00
|
|
|
|
2018-10-28 21:53:21 +01:00
|
|
|
class Connection : public std::enable_shared_from_this< Connection >
|
|
|
|
{
|
|
|
|
friend class Acceptor;
|
|
|
|
friend class Hive;
|
2018-08-29 21:40:59 +02:00
|
|
|
|
2018-10-28 21:53:21 +01:00
|
|
|
protected:
|
|
|
|
HivePtr m_hive;
|
|
|
|
asio::ip::tcp::socket m_socket;
|
|
|
|
asio::strand m_io_strand;
|
|
|
|
std::vector< uint8_t > m_recv_buffer;
|
|
|
|
std::list< int32_t > m_pending_recvs;
|
|
|
|
std::list< std::vector< uint8_t > > m_pending_sends;
|
|
|
|
int32_t m_receive_buffer_size;
|
|
|
|
std::atomic< uint32_t > m_error_state;
|
2018-12-23 03:53:08 +01:00
|
|
|
Sapphire::FrameworkPtr m_pFw;
|
2018-08-29 21:40:59 +02:00
|
|
|
|
2018-12-23 03:53:08 +01:00
|
|
|
Connection( HivePtr hive, FrameworkPtr pFw );
|
2018-08-29 21:40:59 +02:00
|
|
|
|
2018-10-28 21:53:21 +01:00
|
|
|
virtual ~Connection();
|
2018-08-29 21:40:59 +02:00
|
|
|
|
2018-10-28 21:53:21 +01:00
|
|
|
private:
|
|
|
|
Connection( const Connection& rhs );
|
2018-08-29 21:40:59 +02:00
|
|
|
|
2018-10-28 21:53:21 +01:00
|
|
|
Connection& operator=( const Connection& rhs );
|
2018-08-29 21:40:59 +02:00
|
|
|
|
2019-03-08 09:43:56 +01:00
|
|
|
void startSend();
|
2018-08-29 21:40:59 +02:00
|
|
|
|
2019-03-08 09:43:56 +01:00
|
|
|
void startRecv( int32_t total_bytes );
|
2018-08-29 21:40:59 +02:00
|
|
|
|
2019-03-08 09:43:56 +01:00
|
|
|
void startError( const asio::error_code& error );
|
2018-08-29 21:40:59 +02:00
|
|
|
|
2019-03-08 09:43:56 +01:00
|
|
|
void dispatchSend( std::vector< uint8_t > buffer );
|
2018-08-29 21:40:59 +02:00
|
|
|
|
2019-03-08 09:43:56 +01:00
|
|
|
void dispatchRecv( int32_t total_bytes );
|
2018-08-29 21:40:59 +02:00
|
|
|
|
2019-03-08 09:43:56 +01:00
|
|
|
void handleConnect( const asio::error_code& error );
|
2018-08-29 21:40:59 +02:00
|
|
|
|
2019-03-08 09:43:56 +01:00
|
|
|
void handleSend( const asio::error_code& error, std::list< std::vector< uint8_t > >::iterator itr );
|
2018-08-29 21:40:59 +02:00
|
|
|
|
2019-03-08 09:43:56 +01:00
|
|
|
void handleRecv( const asio::error_code& error, int32_t actual_bytes );
|
2017-08-08 13:53:47 +02:00
|
|
|
|
|
|
|
|
2018-10-28 21:53:21 +01:00
|
|
|
private:
|
|
|
|
// Called when the connection has successfully connected to the local host.
|
2019-03-08 09:43:56 +01:00
|
|
|
virtual void onAccept( const std::string& host, uint16_t port )
|
2018-10-28 21:53:21 +01:00
|
|
|
{
|
|
|
|
};
|
2017-08-08 13:53:47 +02:00
|
|
|
|
2018-10-28 21:53:21 +01:00
|
|
|
// Called when the connection has successfully connected to the remote host.
|
2019-03-08 09:43:56 +01:00
|
|
|
virtual void onConnect( const std::string& host, uint16_t port )
|
2018-10-28 21:53:21 +01:00
|
|
|
{
|
|
|
|
};
|
2017-08-08 13:53:47 +02:00
|
|
|
|
2018-10-28 21:53:21 +01:00
|
|
|
// Called when data has been sent by the connection.
|
2019-03-08 09:43:56 +01:00
|
|
|
virtual void onSend( const std::vector< uint8_t >& buffer )
|
2018-10-28 21:53:21 +01:00
|
|
|
{
|
|
|
|
};
|
2017-08-08 13:53:47 +02:00
|
|
|
|
2018-10-28 21:53:21 +01:00
|
|
|
// Called when data has been received by the connection.
|
2019-03-08 09:43:56 +01:00
|
|
|
virtual void onRecv( std::vector< uint8_t >& buffer )
|
2018-10-28 21:53:21 +01:00
|
|
|
{
|
|
|
|
};
|
2018-08-29 21:40:59 +02:00
|
|
|
|
2018-10-28 21:53:21 +01:00
|
|
|
// Called when an error is encountered.
|
2019-03-08 09:43:56 +01:00
|
|
|
virtual void onError( const asio::error_code& error )
|
2018-10-28 21:53:21 +01:00
|
|
|
{
|
|
|
|
};
|
2018-08-29 21:40:59 +02:00
|
|
|
|
2018-10-28 21:53:21 +01:00
|
|
|
// Called when the connection has been disconnected
|
2019-03-08 09:43:56 +01:00
|
|
|
virtual void onDisconnect()
|
2018-10-28 21:53:21 +01:00
|
|
|
{
|
|
|
|
};
|
2018-08-29 21:40:59 +02:00
|
|
|
|
2018-10-28 21:53:21 +01:00
|
|
|
public:
|
|
|
|
// Returns the Hive object.
|
2019-03-08 09:43:56 +01:00
|
|
|
HivePtr getHive();
|
2018-08-29 21:40:59 +02:00
|
|
|
|
2018-10-28 21:53:21 +01:00
|
|
|
// Returns the socket object.
|
2019-03-08 09:43:56 +01:00
|
|
|
asio::ip::tcp::socket& getSocket();
|
2018-08-29 21:40:59 +02:00
|
|
|
|
2018-10-28 21:53:21 +01:00
|
|
|
// Returns the strand object.
|
2019-03-08 09:43:56 +01:00
|
|
|
asio::strand& getStrand();
|
2018-08-29 21:40:59 +02:00
|
|
|
|
2018-10-28 21:53:21 +01:00
|
|
|
// Sets the application specific receive buffer size used. For stream
|
|
|
|
// based protocols such as HTTP, you want this to be pretty large, like
|
|
|
|
// 64kb. For packet based protocols, then it will be much smaller,
|
|
|
|
// usually 512b - 8kb depending on the protocol. The default value is
|
|
|
|
// 4kb.
|
2019-03-08 09:43:56 +01:00
|
|
|
void setReceiveBufferSize( int32_t size );
|
2018-08-29 21:40:59 +02:00
|
|
|
|
2018-10-28 21:53:21 +01:00
|
|
|
// Returns the size of the receive buffer size of the current object.
|
2019-03-08 09:43:56 +01:00
|
|
|
int32_t getReceiveBufferSize() const;
|
2018-08-29 21:40:59 +02:00
|
|
|
|
2018-10-28 21:53:21 +01:00
|
|
|
// Returns true if this object has an error associated with it.
|
2019-03-08 09:43:56 +01:00
|
|
|
bool hasError();
|
2018-08-29 21:40:59 +02:00
|
|
|
|
2018-10-28 21:53:21 +01:00
|
|
|
// Binds the socket to the specified interface.
|
2019-03-08 09:43:56 +01:00
|
|
|
void bind( const std::string& ip, uint16_t port );
|
2018-08-29 21:40:59 +02:00
|
|
|
|
2018-10-28 21:53:21 +01:00
|
|
|
// Starts an a/synchronous connect.
|
2019-03-08 09:43:56 +01:00
|
|
|
void connect( const std::string& host, uint16_t port );
|
2018-08-29 21:40:59 +02:00
|
|
|
|
2018-10-28 21:53:21 +01:00
|
|
|
// Posts data to be sent to the connection.
|
2019-03-08 09:43:56 +01:00
|
|
|
void send( const std::vector< uint8_t >& buffer );
|
2018-08-29 21:40:59 +02:00
|
|
|
|
2018-10-28 21:53:21 +01:00
|
|
|
// Posts a recv for the connection to process. If total_bytes is 0, then
|
|
|
|
// as many bytes as possible up to GetReceiveBufferSize() will be
|
|
|
|
// waited for. If Recv is not 0, then the connection will wait for exactly
|
|
|
|
// total_bytes before invoking OnRecv.
|
2019-03-08 09:43:56 +01:00
|
|
|
void recv( int32_t total_bytes = 0 );
|
2018-08-29 21:40:59 +02:00
|
|
|
|
2018-10-28 21:53:21 +01:00
|
|
|
// Posts an asynchronous disconnect event for the object to process.
|
2019-03-08 09:43:56 +01:00
|
|
|
void disconnect();
|
2018-10-28 21:53:21 +01:00
|
|
|
};
|
2018-08-29 21:40:59 +02:00
|
|
|
|
2018-10-28 21:53:21 +01:00
|
|
|
//-----------------------------------------------------------------------------
|
2018-08-29 21:40:59 +02:00
|
|
|
|
2018-10-28 21:53:21 +01:00
|
|
|
//-----------------------------------------------------------------------------
|
2018-08-29 21:40:59 +02:00
|
|
|
|
2018-10-28 21:53:21 +01:00
|
|
|
template< class T >
|
2018-12-23 03:53:08 +01:00
|
|
|
std::shared_ptr< T > addServerToHive( const std::string& listenIp, uint32_t port, HivePtr pHive, FrameworkPtr pFw )
|
2018-08-29 21:40:59 +02:00
|
|
|
{
|
2018-10-28 21:53:21 +01:00
|
|
|
try
|
|
|
|
{
|
|
|
|
AcceptorPtr acceptor( new Acceptor( pHive ) );
|
2019-03-08 09:43:56 +01:00
|
|
|
acceptor->listen( listenIp, port );
|
2018-12-23 03:53:08 +01:00
|
|
|
std::shared_ptr< T > connection( new T( pHive, acceptor, pFw ) );
|
2019-03-08 09:43:56 +01:00
|
|
|
acceptor->accept( connection );
|
2018-10-28 21:53:21 +01:00
|
|
|
return connection;
|
|
|
|
}
|
|
|
|
catch( std::runtime_error e )
|
|
|
|
{
|
|
|
|
throw;
|
|
|
|
}
|
2018-08-29 21:40:59 +02:00
|
|
|
}
|
2017-08-08 13:53:47 +02:00
|
|
|
|
|
|
|
}
|
2017-12-18 12:36:52 +01:00
|
|
|
#endif
|