Network System 0.1.1
High-performance modular networking library for scalable client-server applications
Loading...
Searching...
No Matches
quic_client_adapter.cpp
Go to the documentation of this file.
1// BSD 3-Clause License
2// Copyright (c) 2024, 🍀☀🌕🌥 🌊
3// See the LICENSE file in the project root for full license information.
4
6
8
9// Enable experimental API for QUIC
10#ifndef NETWORK_USE_EXPERIMENTAL
11#define NETWORK_USE_EXPERIMENTAL
12#endif
13
15
19
21
23 : client_id_(client_id)
24 , client_(std::make_shared<core::messaging_quic_client>(client_id))
25{
27}
28
30{
31 if (client_ && client_->is_running())
32 {
33 (void)client_->stop();
34 }
35}
36
37// =========================================================================
38// QUIC-specific Configuration
39// =========================================================================
40
41auto quic_client_adapter::set_alpn_protocols(const std::vector<std::string>& protocols) -> void
42{
43 alpn_protocols_ = protocols;
44 if (client_)
45 {
46 client_->set_alpn_protocols(protocols);
47 }
48}
49
50auto quic_client_adapter::set_ca_cert_path(std::string_view path) -> void
51{
52 ca_cert_path_ = std::string(path);
53}
54
55auto quic_client_adapter::set_client_cert(std::string_view cert_path, std::string_view key_path) -> void
56{
57 client_cert_path_ = std::string(cert_path);
58 client_key_path_ = std::string(key_path);
59}
60
62{
63 verify_server_ = verify;
64}
65
66auto quic_client_adapter::set_max_idle_timeout(uint64_t timeout_ms) -> void
67{
68 max_idle_timeout_ms_ = timeout_ms;
69}
70
71// =========================================================================
72// i_network_component interface implementation
73// =========================================================================
74
76{
77 return client_ && client_->is_running();
78}
79
81{
82 if (client_)
83 {
84 client_->wait_for_stop();
85 }
86}
87
88// =========================================================================
89// i_protocol_client interface implementation
90// =========================================================================
91
92auto quic_client_adapter::start(std::string_view host, uint16_t port) -> VoidResult
93{
94 if (!client_)
95 {
96 return error_void(
98 "Client not initialized",
99 "quic_client_adapter::start"
100 );
101 }
102
103 // Build configuration
105 config.ca_cert_file = ca_cert_path_;
106 config.client_cert_file = client_cert_path_;
107 config.client_key_file = client_key_path_;
108 config.verify_server = verify_server_;
109 config.alpn_protocols = alpn_protocols_;
110 config.max_idle_timeout_ms = max_idle_timeout_ms_;
111
112 return client_->start_client(host, port, config);
113}
114
116{
117 if (!client_)
118 {
119 return error_void(
121 "Client not initialized",
122 "quic_client_adapter::stop"
123 );
124 }
125
126 return client_->stop_client();
127}
128
129auto quic_client_adapter::send(std::vector<uint8_t>&& data) -> VoidResult
130{
131 if (!client_)
132 {
133 return error_void(
135 "Client not initialized",
136 "quic_client_adapter::send"
137 );
138 }
139
140 if (!client_->is_connected())
141 {
142 return error_void(
144 "Client is not connected",
145 "quic_client_adapter::send"
146 );
147 }
148
149 return client_->send(std::move(data));
150}
151
153{
154 return client_ && client_->is_connected();
155}
156
157auto quic_client_adapter::set_observer(std::shared_ptr<interfaces::connection_observer> observer) -> void
158{
159 std::lock_guard<std::mutex> lock(callbacks_mutex_);
160 observer_ = std::move(observer);
161}
162
164{
165 std::lock_guard<std::mutex> lock(callbacks_mutex_);
166 receive_callback_ = std::move(callback);
167}
168
170{
171 std::lock_guard<std::mutex> lock(callbacks_mutex_);
172 connected_callback_ = std::move(callback);
173}
174
176{
177 std::lock_guard<std::mutex> lock(callbacks_mutex_);
178 disconnected_callback_ = std::move(callback);
179}
180
182{
183 std::lock_guard<std::mutex> lock(callbacks_mutex_);
184 error_callback_ = std::move(callback);
185}
186
187// =========================================================================
188// Internal methods
189// =========================================================================
190
192{
193 if (!client_)
194 {
195 return;
196 }
197
198 // Bridge receive callback
199 client_->set_receive_callback([this](const std::vector<uint8_t>& data) {
200 std::shared_ptr<interfaces::connection_observer> observer_copy;
201 receive_callback_t callback_copy;
202 {
203 std::lock_guard<std::mutex> lock(callbacks_mutex_);
204 observer_copy = observer_;
205 callback_copy = receive_callback_;
206 }
207
208 if (observer_copy)
209 {
210 observer_copy->on_receive(data);
211 }
212 if (callback_copy)
213 {
214 callback_copy(data);
215 }
216 });
217
218 // Bridge connected callback
219 client_->set_connected_callback([this]() {
220 std::shared_ptr<interfaces::connection_observer> observer_copy;
221 connected_callback_t callback_copy;
222 {
223 std::lock_guard<std::mutex> lock(callbacks_mutex_);
224 observer_copy = observer_;
225 callback_copy = connected_callback_;
226 }
227
228 if (observer_copy)
229 {
230 observer_copy->on_connected();
231 }
232 if (callback_copy)
233 {
234 callback_copy();
235 }
236 });
237
238 // Bridge disconnected callback
239 client_->set_disconnected_callback([this]() {
240 std::shared_ptr<interfaces::connection_observer> observer_copy;
241 disconnected_callback_t callback_copy;
242 {
243 std::lock_guard<std::mutex> lock(callbacks_mutex_);
244 observer_copy = observer_;
245 callback_copy = disconnected_callback_;
246 }
247
248 if (observer_copy)
249 {
250 observer_copy->on_disconnected();
251 }
252 if (callback_copy)
253 {
254 callback_copy();
255 }
256 });
257
258 // Bridge error callback
259 client_->set_error_callback([this](std::error_code ec) {
260 std::shared_ptr<interfaces::connection_observer> observer_copy;
261 error_callback_t callback_copy;
262 {
263 std::lock_guard<std::mutex> lock(callbacks_mutex_);
264 observer_copy = observer_;
265 callback_copy = error_callback_;
266 }
267
268 if (observer_copy)
269 {
270 observer_copy->on_error(ec);
271 }
272 if (callback_copy)
273 {
274 callback_copy(ec);
275 }
276 });
277}
278
279} // namespace kcenon::network::internal::adapters
std::function< void(const std::vector< uint8_t > &)> receive_callback_t
Callback type for received data.
std::function< void()> connected_callback_t
Callback type for connection established.
std::function< void(std::error_code)> error_callback_t
Callback type for errors.
std::function< void()> disconnected_callback_t
Callback type for disconnection.
auto is_connected() const -> bool override
Checks if the client is connected to the server.
auto set_max_idle_timeout(uint64_t timeout_ms) -> void
Sets max idle timeout in milliseconds.
auto set_connected_callback(connected_callback_t callback) -> void override
Sets the callback for connection established.
auto send(std::vector< uint8_t > &&data) -> VoidResult override
Sends data to the connected server.
auto set_verify_server(bool verify) -> void
Sets whether to verify server certificate.
quic_client_adapter(std::string_view client_id)
Constructs an adapter with a unique client ID.
auto wait_for_stop() -> void override
Blocks until the component has stopped.
auto stop() -> VoidResult override
Stops the client and closes the connection.
auto set_client_cert(std::string_view cert_path, std::string_view key_path) -> void
Sets client certificate path for mutual TLS.
auto set_receive_callback(receive_callback_t callback) -> void override
Sets the callback for received data.
auto is_running() const -> bool override
Checks if the component is currently running.
auto setup_internal_callbacks() -> void
Sets up internal callbacks to bridge QUIC callbacks to i_protocol_client callbacks.
auto set_observer(std::shared_ptr< interfaces::connection_observer > observer) -> void override
Sets the connection observer for unified event handling.
auto set_alpn_protocols(const std::vector< std::string > &protocols) -> void
Sets the ALPN protocols for negotiation.
auto set_disconnected_callback(disconnected_callback_t callback) -> void override
Sets the callback for disconnection.
std::shared_ptr< core::messaging_quic_client > client_
~quic_client_adapter() override
Destructor ensures proper cleanup.
auto set_ca_cert_path(std::string_view path) -> void
Sets CA certificate path for server verification.
auto set_error_callback(error_callback_t callback) -> void override
Sets the callback for errors.
auto start(std::string_view host, uint16_t port) -> VoidResult override
Starts the client and connects to the specified server.
tracing_config config
Definition exporters.cpp:29
VoidResult error_void(int code, const std::string &message, const std::string &source="network_system", const std::string &details="")
VoidResult ok()
Network-specific error and result type definitions.
Configuration options for QUIC client.
Definition quic_client.h:51