Network System 0.1.1
High-performance modular networking library for scalable client-server applications
Loading...
Searching...
No Matches
tcp_connection_adapter.cpp
Go to the documentation of this file.
1// BSD 3-Clause License
2// Copyright (c) 2025, 🍀☀🌕🌥 🌊
3// See the LICENSE file in the project root for full license information.
4
6
7#include <algorithm>
8#include <cstring>
9
11
13 : connection_id_(connection_id)
14 , client_(std::make_shared<core::tcp_client>(connection_id))
15{
17}
18
23
24auto tcp_connection_adapter::send(std::span<const std::byte> data) -> VoidResult
25{
26 if (!client_ || !client_->is_connected()) {
27 return error_void(
28 static_cast<int>(std::errc::not_connected),
29 "Connection is not established"
30 );
31 }
32
33 std::vector<uint8_t> buffer(data.size());
34 std::memcpy(buffer.data(), data.data(), data.size());
35
36 return client_->send_packet(std::move(buffer));
37}
38
39auto tcp_connection_adapter::send(std::vector<uint8_t>&& data) -> VoidResult
40{
41 if (!client_ || !client_->is_connected()) {
42 return error_void(
43 static_cast<int>(std::errc::not_connected),
44 "Connection is not established"
45 );
46 }
47
48 return client_->send_packet(std::move(data));
49}
50
51auto tcp_connection_adapter::is_connected() const noexcept -> bool
52{
53 return client_ && client_->is_connected();
54}
55
56auto tcp_connection_adapter::id() const noexcept -> std::string_view
57{
58 return connection_id_;
59}
60
62{
63 std::lock_guard lock(endpoint_mutex_);
64 return remote_endpoint_;
65}
66
68{
69 std::lock_guard lock(endpoint_mutex_);
70 return local_endpoint_;
71}
72
74{
75 if (!client_) {
76 return error_void(
77 static_cast<int>(std::errc::invalid_argument),
78 "Client is not initialized"
79 );
80 }
81
82 if (client_->is_connected() || client_->is_running()) {
83 return error_void(
84 static_cast<int>(std::errc::already_connected),
85 "Already connected or connecting"
86 );
87 }
88
89 {
90 std::lock_guard lock(endpoint_mutex_);
91 remote_endpoint_ = endpoint;
92 }
93
94 is_connecting_ = true;
95 auto result = client_->start_client(endpoint.host, endpoint.port);
96
97 if (!result.is_ok()) {
98 is_connecting_ = false;
99 }
100
101 return result;
102}
103
104auto tcp_connection_adapter::connect(std::string_view url) -> VoidResult
105{
106 // Parse URL for TCP: expect format "tcp://host:port" or just "host:port"
107 std::string url_str(url);
108
109 // Remove tcp:// prefix if present
110 const std::string tcp_prefix = "tcp://";
111 if (url_str.substr(0, tcp_prefix.size()) == tcp_prefix) {
112 url_str = url_str.substr(tcp_prefix.size());
113 }
114
115 // Find the last colon for port separation
116 auto colon_pos = url_str.rfind(':');
117 if (colon_pos == std::string::npos) {
118 return error_void(
119 static_cast<int>(std::errc::invalid_argument),
120 "URL must contain port number (format: host:port)"
121 );
122 }
123
124 std::string host = url_str.substr(0, colon_pos);
125 std::string port_str = url_str.substr(colon_pos + 1);
126
127 uint16_t port = 0;
128 try {
129 port = static_cast<uint16_t>(std::stoi(port_str));
130 } catch (...) {
131 return error_void(
132 static_cast<int>(std::errc::invalid_argument),
133 "Invalid port number in URL"
134 );
135 }
136
137 return connect(endpoint_info{host, port});
138}
139
140auto tcp_connection_adapter::close() noexcept -> void
141{
142 if (client_ && client_->is_running()) {
143 (void)client_->stop_client();
144 }
145 is_connecting_ = false;
146}
147
149{
150 {
151 std::lock_guard lock(callbacks_mutex_);
152 callbacks_ = std::move(callbacks);
153 }
154
155 // Re-setup internal callbacks to use the new user callbacks
156 setup_internal_callbacks();
157}
158
160{
161 options_ = options;
162 // Note: Current unified_messaging_client doesn't expose timeout configuration
163 // This would need to be added to the underlying implementation
164}
165
166auto tcp_connection_adapter::set_timeout(std::chrono::milliseconds timeout) -> void
167{
168 options_.connect_timeout = timeout;
169}
170
171auto tcp_connection_adapter::is_connecting() const noexcept -> bool
172{
173 return is_connecting_.load();
174}
175
177{
178 if (client_) {
179 client_->wait_for_stop();
180 }
181}
182
184{
185 if (!client_) {
186 return;
187 }
188
189 // Bridge receive callback
190 client_->set_receive_callback([this](const std::vector<uint8_t>& data) {
191 std::lock_guard lock(callbacks_mutex_);
192 if (callbacks_.on_data) {
193 std::span<const std::byte> byte_span(
194 reinterpret_cast<const std::byte*>(data.data()),
195 data.size()
196 );
197 callbacks_.on_data(byte_span);
198 }
199 });
200
201 // Bridge connected callback
202 client_->set_connected_callback([this]() {
203 is_connecting_ = false;
204
205 std::lock_guard lock(callbacks_mutex_);
206 if (callbacks_.on_connected) {
207 callbacks_.on_connected();
208 }
209 });
210
211 // Bridge disconnected callback
212 client_->set_disconnected_callback([this]() {
213 is_connecting_ = false;
214
215 std::lock_guard lock(callbacks_mutex_);
216 if (callbacks_.on_disconnected) {
217 callbacks_.on_disconnected();
218 }
219 });
220
221 // Bridge error callback
222 client_->set_error_callback([this](std::error_code ec) {
223 is_connecting_ = false;
224
225 std::lock_guard lock(callbacks_mutex_);
226 if (callbacks_.on_error) {
227 callbacks_.on_error(ec);
228 }
229 });
230}
231
232} // namespace kcenon::network::unified::adapters
auto id() const noexcept -> std::string_view override
Gets the unique identifier for this transport/connection.
auto set_callbacks(connection_callbacks callbacks) -> void override
Sets all connection callbacks at once.
tcp_connection_adapter(std::string_view connection_id)
Constructs an adapter with a unique connection ID.
auto set_options(connection_options options) -> void override
Sets connection options.
auto setup_internal_callbacks() -> void
Sets up internal callbacks to bridge to unified callbacks.
auto connect(const endpoint_info &endpoint) -> VoidResult override
Connects to a remote endpoint using host/port.
auto close() noexcept -> void override
Closes the connection gracefully.
auto is_connecting() const noexcept -> bool override
Checks if the connection is in the process of connecting.
auto is_connected() const noexcept -> bool override
Checks if the transport is currently connected.
auto send(std::span< const std::byte > data) -> VoidResult override
Sends raw data to the remote endpoint.
auto set_timeout(std::chrono::milliseconds timeout) -> void override
Sets the connection timeout.
~tcp_connection_adapter() override
Destructor ensures proper cleanup.
auto remote_endpoint() const noexcept -> endpoint_info override
Gets the remote endpoint information.
auto wait_for_stop() -> void override
Blocks until the component has stopped.
auto local_endpoint() const noexcept -> endpoint_info override
Gets the local endpoint information.
VoidResult error_void(int code, const std::string &message, const std::string &source="network_system", const std::string &details="")
Callback functions for connection events.
Definition types.h:154
Configuration options for connections.
Definition types.h:198
Network endpoint information (host/port or URL)
Definition types.h:56