15 asio::ssl::context& ssl_context)
16 : ssl_stream_(std::move(socket), ssl_context)
21 asio::ssl::stream_base::handshake_type type,
22 std::function<
void(std::error_code)> handler) ->
void
24 auto self = shared_from_this();
25 ssl_stream_.async_handshake(
27 [handler = std::move(handler), self](std::error_code ec)
29 if constexpr (std::is_invocable_v<
decltype(handler), std::error_code>)
40 std::function<
void(
const std::vector<uint8_t>&)> callback) ->
void
42 auto new_cb = std::make_shared<receive_callback_t>(std::move(callback));
43 std::lock_guard<std::mutex> lock(callback_mutex_);
44 std::atomic_store(&receive_callback_, new_cb);
48 std::function<
void(std::span<const uint8_t>)> callback) ->
void
50 auto new_cb = std::make_shared<receive_callback_view_t>(std::move(callback));
51 std::lock_guard<std::mutex> lock(callback_mutex_);
52 std::atomic_store(&receive_callback_view_, new_cb);
56 std::function<
void(std::error_code)> callback) ->
void
58 auto new_cb = std::make_shared<error_callback_t>(std::move(callback));
59 std::lock_guard<std::mutex> lock(callback_mutex_);
60 std::atomic_store(&error_callback_, new_cb);
66 is_reading_.store(
true);
73 is_reading_.store(
false);
80 is_closed_.store(
true);
81 is_reading_.store(
false);
84 ssl_stream_.lowest_layer().close(ec);
96 if (!is_reading_.load())
104 if (is_closed_.load() || !ssl_stream_.lowest_layer().is_open())
106 is_reading_.store(
false);
110 auto self = shared_from_this();
111 ssl_stream_.async_read_some(
112 asio::buffer(read_buffer_),
113 [
this, self](std::error_code ec, std::size_t length)
117 if (!is_reading_.load() || is_closed_.load())
126 auto error_cb = std::atomic_load(&error_callback_);
127 if (error_cb && *error_cb)
139 auto view_cb = std::atomic_load(&receive_callback_view_);
140 if (view_cb && *view_cb)
144 std::span<const uint8_t> data_view(read_buffer_.data(), length);
145 (*view_cb)(data_view);
150 auto recv_cb = std::atomic_load(&receive_callback_);
151 if (recv_cb && *recv_cb)
153 std::vector<uint8_t> chunk(read_buffer_.begin(),
154 read_buffer_.begin() + length);
162 if (is_reading_.load() && !is_closed_.load())
170 std::vector<uint8_t>&& data,
171 std::function<
void(std::error_code, std::size_t)> handler) ->
void
175 if (is_closed_.load())
179 handler(asio::error::not_connected, 0);
184 auto self = shared_from_this();
186 auto buffer = std::make_shared<std::vector<uint8_t>>(std::move(data));
188 ssl_stream_, asio::buffer(*buffer),
189 [handler = std::move(handler), self, buffer](std::error_code ec, std::size_t bytes_transferred)
191 if constexpr (std::is_invocable_v<
decltype(handler), std::error_code, std::size_t>)
195 handler(ec, bytes_transferred);
auto set_receive_callback(std::function< void(const std::vector< uint8_t > &)> callback) -> void
Sets a callback to receive inbound data chunks.
secure_tcp_socket(asio::ip::tcp::socket socket, asio::ssl::context &ssl_context)
Constructs a secure_tcp_socket by taking ownership of a moved socket and SSL context.
auto async_handshake(asio::ssl::stream_base::handshake_type type, std::function< void(std::error_code)> handler) -> void
Performs asynchronous SSL handshake.
auto close() -> void
Safely closes the socket and stops all async operations.
std::atomic< bool > is_closed_
auto start_read() -> void
Begins the continuous asynchronous read loop.
auto async_send(std::vector< uint8_t > &&data, std::function< void(std::error_code, std::size_t)> handler) -> void
Initiates an asynchronous write of the given data buffer with encryption.
auto do_read() -> void
Internal function to handle the read logic with async_read_some().
auto is_closed() const -> bool
Checks if the socket has been closed.
auto set_receive_callback_view(std::function< void(std::span< const uint8_t >)> callback) -> void
Sets a zero-copy callback to receive inbound data as a view.
auto set_error_callback(std::function< void(std::error_code)> callback) -> void
Sets a callback to handle socket errors (e.g., read/write failures).
auto stop_read() -> void
Stops the read loop to prevent further async operations.