Network System 0.1.1
High-performance modular networking library for scalable client-server applications
Loading...
Searching...
No Matches
ws_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
10
12 std::string_view client_id,
13 std::chrono::milliseconds ping_interval)
14 : client_id_(client_id)
15 , ping_interval_(ping_interval)
16 , client_(std::make_shared<core::messaging_ws_client>(std::string(client_id)))
17{
19}
20
22{
23 if (client_ && client_->is_running())
24 {
25 (void)client_->stop();
26 }
27}
28
29// =========================================================================
30// Path Configuration
31// =========================================================================
32
33auto ws_client_adapter::set_path(std::string_view path) -> void
34{
35 path_ = std::string(path);
36}
37
38// =========================================================================
39// i_network_component interface implementation
40// =========================================================================
41
43{
44 return client_ && client_->is_running();
45}
46
48{
49 if (client_)
50 {
51 client_->wait_for_stop();
52 }
53}
54
55// =========================================================================
56// i_protocol_client interface implementation
57// =========================================================================
58
59auto ws_client_adapter::start(std::string_view host, uint16_t port) -> VoidResult
60{
61 if (!client_)
62 {
63 return error_void(
65 "Client not initialized",
66 "ws_client_adapter::start"
67 );
68 }
69
70 // Use the stored path (set via set_path, or default "/")
71 return client_->start(host, port, path_);
72}
73
75{
76 if (!client_)
77 {
78 return error_void(
80 "Client not initialized",
81 "ws_client_adapter::stop"
82 );
83 }
84
85 return client_->stop();
86}
87
88auto ws_client_adapter::send(std::vector<uint8_t>&& data) -> VoidResult
89{
90 if (!client_)
91 {
92 return error_void(
94 "Client not initialized",
95 "ws_client_adapter::send"
96 );
97 }
98
99 if (!client_->is_connected())
100 {
101 return error_void(
103 "Client is not connected - call start() first",
104 "ws_client_adapter::send"
105 );
106 }
107
108 // Send as binary WebSocket frame
109 return client_->send_binary(std::move(data));
110}
111
113{
114 return client_ && client_->is_connected();
115}
116
117auto ws_client_adapter::set_observer(std::shared_ptr<interfaces::connection_observer> observer) -> void
118{
119 std::lock_guard<std::mutex> lock(callbacks_mutex_);
120 observer_ = std::move(observer);
121}
122
124{
125 std::lock_guard<std::mutex> lock(callbacks_mutex_);
126 receive_callback_ = std::move(callback);
127}
128
130{
131 std::lock_guard<std::mutex> lock(callbacks_mutex_);
132 connected_callback_ = std::move(callback);
133}
134
136{
137 std::lock_guard<std::mutex> lock(callbacks_mutex_);
138 disconnected_callback_ = std::move(callback);
139}
140
142{
143 std::lock_guard<std::mutex> lock(callbacks_mutex_);
144 error_callback_ = std::move(callback);
145}
146
147// =========================================================================
148// Internal methods
149// =========================================================================
150
152{
153 if (!client_)
154 {
155 return;
156 }
157
158 // Bridge WebSocket binary callback to i_protocol_client receive callback
159 client_->set_binary_callback(
160 [this](const std::vector<uint8_t>& data)
161 {
162 std::shared_ptr<interfaces::connection_observer> observer_copy;
163 receive_callback_t callback_copy;
164 {
165 std::lock_guard<std::mutex> lock(callbacks_mutex_);
166 observer_copy = observer_;
167 callback_copy = receive_callback_;
168 }
169
170 if (observer_copy)
171 {
172 observer_copy->on_receive(data);
173 }
174 if (callback_copy)
175 {
176 callback_copy(data);
177 }
178 });
179
180 // Bridge WebSocket connected callback
181 client_->set_connected_callback(
182 [this]()
183 {
184 std::shared_ptr<interfaces::connection_observer> observer_copy;
185 connected_callback_t callback_copy;
186 {
187 std::lock_guard<std::mutex> lock(callbacks_mutex_);
188 observer_copy = observer_;
189 callback_copy = connected_callback_;
190 }
191
192 if (observer_copy)
193 {
194 observer_copy->on_connected();
195 }
196 if (callback_copy)
197 {
198 callback_copy();
199 }
200 });
201
202 // Bridge WebSocket disconnected callback (ignore close code and reason)
203 client_->set_disconnected_callback(
204 [this](uint16_t /* code */, std::string_view /* reason */)
205 {
206 std::shared_ptr<interfaces::connection_observer> observer_copy;
207 disconnected_callback_t callback_copy;
208 {
209 std::lock_guard<std::mutex> lock(callbacks_mutex_);
210 observer_copy = observer_;
211 callback_copy = disconnected_callback_;
212 }
213
214 if (observer_copy)
215 {
216 observer_copy->on_disconnected();
217 }
218 if (callback_copy)
219 {
220 callback_copy();
221 }
222 });
223
224 // Bridge WebSocket error callback
225 client_->set_error_callback(
226 [this](std::error_code ec)
227 {
228 std::shared_ptr<interfaces::connection_observer> observer_copy;
229 error_callback_t callback_copy;
230 {
231 std::lock_guard<std::mutex> lock(callbacks_mutex_);
232 observer_copy = observer_;
233 callback_copy = error_callback_;
234 }
235
236 if (observer_copy)
237 {
238 observer_copy->on_error(ec);
239 }
240 if (callback_copy)
241 {
242 callback_copy(ec);
243 }
244 });
245}
246
247} // 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 stop() -> VoidResult override
Stops the client and closes the connection.
auto set_path(std::string_view path) -> void
Sets the WebSocket path for connection.
auto set_disconnected_callback(disconnected_callback_t callback) -> void override
Sets the callback for disconnection.
auto wait_for_stop() -> void override
Blocks until the component has stopped.
std::shared_ptr< core::messaging_ws_client > client_
auto setup_internal_callbacks() -> void
Sets up internal callbacks to bridge WebSocket callbacks to i_protocol_client callbacks.
auto set_receive_callback(receive_callback_t callback) -> void override
Sets the callback for received data.
~ws_client_adapter() override
Destructor ensures proper cleanup.
auto start(std::string_view host, uint16_t port) -> VoidResult override
Starts the client and connects to the specified server.
auto is_running() const -> bool override
Checks if the component is currently running.
auto is_connected() const -> bool override
Checks if the client is connected to the server.
auto send(std::vector< uint8_t > &&data) -> VoidResult override
Sends data to the connected server.
auto set_observer(std::shared_ptr< interfaces::connection_observer > observer) -> void override
Sets the connection observer for unified event handling.
auto set_connected_callback(connected_callback_t callback) -> void override
Sets the callback for connection established.
auto set_error_callback(error_callback_t callback) -> void override
Sets the callback for errors.
ws_client_adapter(std::string_view client_id, std::chrono::milliseconds ping_interval=std::chrono::seconds(30))
Constructs an adapter with a unique client ID.
VoidResult error_void(int code, const std::string &message, const std::string &source="network_system", const std::string &details="")