30#ifndef HORIZON_NETWORKING_SOCKET_HPP
31#define HORIZON_NETWORKING_SOCKET_HPP
43#include <boost/asio/ip/tcp.hpp>
44#include <boost/bind/bind.hpp>
45#include <boost/asio/write.hpp>
46#include <boost/asio/use_future.hpp>
50using boost::asio::ip::tcp;
52#define READ_BLOCK_SIZE 0x1000
53#define BOOST_BIND_GLOBAL_PLACEHOLDERS 1
80template <
class SocketType>
81class Socket :
public std::enable_shared_from_this<SocketType>
90 explicit Socket(uint64_t socket_id, std::shared_ptr<tcp::socket> socket)
99 boost::system::error_code error;
178 boost::system::error_code socket_error;
190 _socket->shutdown(boost::asio::socket_base::shutdown_send, socket_error);
195 HLog(error) <<
"Error when shutting down socket from IP " <<
196 remote_ip_address() <<
"(error code:" << socket_error.value() <<
" - " << socket_error.message().c_str() <<
")";
220 _socket->async_write_some(boost::asio::null_buffers(),
222 this, boost::placeholders::_1, boost::placeholders::_2));
233 boost::system::error_code error;
234 _socket->set_option(tcp::no_delay(enable), error);
236 HLog(error) <<
"Networking: Socket::set_no_delay: failed to set_option(boost::asio::ip::tcp::no_delay) for IP " <<
remote_ip_address() <<
" (error_code: " << error.value() <<
" - " << error.message().c_str() <<
")";
251 std::size_t bytes_sent =
_socket->write_some(boost::asio::buffer(to_send.
get_read_pointer(), bytes_to_send), error);
267 if (error.value() == boost::asio::error::eof) {
270 }
else if (error.value() == boost::system::errc::connection_reset
271 || error.value() == boost::system::errc::timed_out) {
280 switch (error.value())
285 HLog(debug) <<
"Socket::read_handler_internal: " << error.value() <<
" (Code: " << error.message() <<
").";
290 if (transferredBytes > 0) {
319 boost::system::error_code error;
333 if (error == boost::asio::error::would_block || error == boost::asio::error::try_again)
339 if (!error && bytes_sent < to_send->active_length()) {
340 to_send->read_completed(bytes_sent);
#define HLog(type)
Definition: Logger.hpp:122
#define READ_BLOCK_SIZE
Definition: Socket.hpp:52
Definition: ByteBuffer.hpp:78
void ensure_free_space()
Definition: ByteBuffer.hpp:350
size_t remaining_space() const
Definition: ByteBuffer.hpp:334
void resize(size_t new_size)
Definition: ByteBuffer.hpp:357
uint8_t * get_write_pointer()
Definition: ByteBuffer.hpp:328
uint8_t * get_read_pointer()
Definition: ByteBuffer.hpp:327
void flush()
Definition: ByteBuffer.hpp:339
void write_completed(size_t bytes)
Definition: ByteBuffer.hpp:322
size_t active_length() const
Definition: ByteBuffer.hpp:333
A Socket object that handles a single connection.
Definition: Socket.hpp:82
ByteBuffer & get_read_buffer()
Definition: Socket.hpp:202
virtual void start()=0
Initial method invoked once from the network thread that handles the AuthSocket.
ThreadSafeQueue< ByteBuffer > _write_queue
Definition: Socket.hpp:363
virtual ~Socket()
Definition: Socket.hpp:97
uint16_t _remote_port
Definition: Socket.hpp:361
bool _is_writing_async
Definition: Socket.hpp:366
void close_socket()
Socket close operation that performs cleanups before shutting down the connection.
Definition: Socket.hpp:176
bool async_process_queue()
Socket write operation.
Definition: Socket.hpp:213
virtual void on_close()=0
Socket(uint64_t socket_id, std::shared_ptr< tcp::socket > socket)
Definition: Socket.hpp:90
ByteBuffer _read_buffer
Definition: Socket.hpp:362
uint64_t get_socket_id()
Definition: Socket.hpp:130
void async_read_with_callback(ByteBuffer &buf, void(Socket< SocketType >::*)(boost::system::error_code, std::size_t))
Asynchronous read operation with callback handler @thread NetworkThread.
Definition: Socket.hpp:156
Socket(uint64_t socket_id)
Definition: Socket.hpp:84
void delayed_close_socket()
Definition: Socket.hpp:200
void write_handler_wrapper(boost::system::error_code, std::size_t)
Write handler wrapper.
Definition: Socket.hpp:306
uint16_t remote_port() const
Definition: Socket.hpp:134
virtual void read_handler()=0
virtual void on_error()=0
void async_read()
Asynchronous read operation @thread NetworkThread.
Definition: Socket.hpp:140
void read_handler_internal(boost::system::error_code error, size_t transferredBytes)
Aysnchronous reading handler method.
Definition: Socket.hpp:262
std::size_t write_buffer_and_send(ByteBuffer &to_send, boost::system::error_code &error)
Write a message to the buffer.
Definition: Socket.hpp:246
uint64_t _socket_id
Definition: Socket.hpp:358
std::atomic< bool > _closing
Definition: Socket.hpp:365
std::string & remote_ip_address()
Definition: Socket.hpp:133
std::shared_ptr< tcp::socket > get_socket()
Definition: Socket.hpp:355
std::string _remote_ip_address
Definition: Socket.hpp:360
bool handle_queue()
Handle the queue.
Definition: Socket.hpp:317
void set_no_delay(bool enable)
Disable the Nagle Algorithm on our socket.
Definition: Socket.hpp:231
bool is_open()
Definition: Socket.hpp:170
std::atomic< bool > _closed
Definition: Socket.hpp:364
virtual void queue_buffer(ByteBuffer &&buffer)
Definition: Socket.hpp:168
std::shared_ptr< tcp::socket > _socket
After accepting, the reference count of this pointer should be 1.
Definition: Socket.hpp:359
virtual bool update()
Socket update loop called from its NetworkThread every n nanoseconds.
Definition: Socket.hpp:114
bool empty()
Definition: ThreadSafeQueue.hpp:116
std::shared_ptr< T > front()
Definition: ThreadSafeQueue.hpp:126
void push(T &&new_value)
Definition: ThreadSafeQueue.hpp:90
std::shared_ptr< T > try_pop()
Definition: ThreadSafeQueue.hpp:84
Definition: Element.hpp:7