14 : connection_id_(connection_id)
15 , client_(std::make_shared<core::messaging_ws_client>(connection_id))
27 if (!client_ || !client_->is_connected()) {
29 static_cast<int>(std::errc::not_connected),
30 "WebSocket is not connected"
34 std::vector<uint8_t> buffer(data.size());
35 std::memcpy(buffer.data(), data.data(), data.size());
37 return client_->send_binary(std::move(buffer));
42 if (!client_ || !client_->is_connected()) {
44 static_cast<int>(std::errc::not_connected),
45 "WebSocket is not connected"
49 return client_->send_binary(std::move(data));
78 static_cast<int>(std::errc::invalid_argument),
79 "Client is not initialized"
83 if (client_->is_connected() || client_->is_running()) {
85 static_cast<int>(std::errc::already_connected),
86 "Already connected or connecting"
91 std::lock_guard lock(endpoint_mutex_);
92 remote_endpoint_ = endpoint;
95 is_connecting_ =
true;
98 uint16_t port = endpoint.port;
103 auto result = client_->start_client(endpoint.host, port, ws_path_);
105 if (!result.is_ok()) {
106 is_connecting_ =
false;
116 static_cast<int>(std::errc::invalid_argument),
117 "Client is not initialized"
121 if (client_->is_connected() || client_->is_running()) {
123 static_cast<int>(std::errc::already_connected),
124 "Already connected or connecting"
133 if (!parse_websocket_url(url, host, port, path, secure)) {
135 static_cast<int>(std::errc::invalid_argument),
136 "Invalid WebSocket URL format. Expected: ws://host:port/path or wss://host:port/path"
141 std::lock_guard lock(endpoint_mutex_);
145 is_connecting_ =
true;
147 auto result = client_->start_client(host, port, path);
149 if (!result.is_ok()) {
150 is_connecting_ =
false;
167 std::lock_guard lock(callbacks_mutex_);
168 callbacks_ = std::move(callbacks);
171 setup_internal_callbacks();
181 options_.connect_timeout = timeout;
192 client_->wait_for_stop();
198 ws_path_ = std::string(path);
208 client_->set_binary_callback([
this](
const std::vector<uint8_t>& data) {
209 std::lock_guard lock(callbacks_mutex_);
210 if (callbacks_.on_data) {
211 std::span<const std::byte> byte_span(
212 reinterpret_cast<const std::byte*
>(data.data()),
215 callbacks_.on_data(byte_span);
220 client_->set_text_callback([
this](
const std::string& text) {
221 std::lock_guard lock(callbacks_mutex_);
222 if (callbacks_.on_data) {
223 std::span<const std::byte> byte_span(
224 reinterpret_cast<const std::byte*
>(text.data()),
227 callbacks_.on_data(byte_span);
232 client_->set_connected_callback([
this]() {
233 is_connecting_ =
false;
235 std::lock_guard lock(callbacks_mutex_);
236 if (callbacks_.on_connected) {
237 callbacks_.on_connected();
242 client_->set_disconnected_callback([
this](uint16_t , std::string_view ) {
243 is_connecting_ =
false;
245 std::lock_guard lock(callbacks_mutex_);
246 if (callbacks_.on_disconnected) {
247 callbacks_.on_disconnected();
252 client_->set_error_callback([
this](std::error_code ec) {
253 is_connecting_ =
false;
255 std::lock_guard lock(callbacks_mutex_);
256 if (callbacks_.on_error) {
257 callbacks_.on_error(ec);
266 bool& secure) ->
bool
268 std::string url_str(url);
272 std::string remaining;
274 if (url_str.substr(0, 6) ==
"wss://") {
276 remaining = url_str.substr(6);
277 }
else if (url_str.substr(0, 5) ==
"ws://") {
279 remaining = url_str.substr(5);
286 auto path_pos = remaining.find(
'/');
287 std::string host_port;
288 if (path_pos != std::string::npos) {
289 host_port = remaining.substr(0, path_pos);
290 path = remaining.substr(path_pos);
292 host_port = remaining;
297 auto colon_pos = host_port.rfind(
':');
300 bool is_ipv6 = host_port.find(
'[') != std::string::npos;
303 auto bracket_end = host_port.find(
']');
304 if (bracket_end == std::string::npos) {
308 host = host_port.substr(0, bracket_end + 1);
310 if (bracket_end + 1 < host_port.size() && host_port[bracket_end + 1] ==
':') {
311 std::string port_str = host_port.substr(bracket_end + 2);
313 port =
static_cast<uint16_t
>(std::stoi(port_str));
318 port = secure ? 443 : 80;
320 }
else if (colon_pos != std::string::npos) {
321 host = host_port.substr(0, colon_pos);
322 std::string port_str = host_port.substr(colon_pos + 1);
324 port =
static_cast<uint16_t
>(std::stoi(port_str));
330 port = secure ? 443 : 80;
333 return !host.empty();
static auto parse_websocket_url(std::string_view url, std::string &host, uint16_t &port, std::string &path, bool &secure) -> bool
Parses a WebSocket URL into components.
auto set_timeout(std::chrono::milliseconds timeout) -> void override
Sets the connection timeout.
auto send(std::span< const std::byte > data) -> VoidResult override
Sends raw data to the remote endpoint.
auto set_callbacks(connection_callbacks callbacks) -> void override
Sets all connection callbacks at once.
auto connect(const endpoint_info &endpoint) -> VoidResult override
Connects to a remote endpoint using host/port.
auto setup_internal_callbacks() -> void
Sets up internal callbacks to bridge to unified callbacks.
auto set_path(std::string_view path) -> void
Sets the WebSocket path for endpoint-based connections.
auto wait_for_stop() -> void override
Blocks until the component has stopped.
std::mutex endpoint_mutex_
std::atomic< bool > is_connecting_
endpoint_info remote_endpoint_
auto close() noexcept -> void override
Closes the connection gracefully.
auto set_options(connection_options options) -> void override
Sets connection options.
auto id() const noexcept -> std::string_view override
Gets the unique identifier for this transport/connection.
auto remote_endpoint() const noexcept -> endpoint_info override
Gets the remote endpoint information.
endpoint_info local_endpoint_
ws_connection_adapter(std::string_view connection_id)
Constructs an adapter with a unique connection ID.
std::shared_ptr< core::messaging_ws_client > client_
std::string connection_id_
auto local_endpoint() const noexcept -> endpoint_info override
Gets the local endpoint information.
auto is_connecting() const noexcept -> bool override
Checks if the connection is in the process of connecting.
~ws_connection_adapter() override
Destructor ensures proper cleanup.
auto is_connected() const noexcept -> bool override
Checks if the transport is currently connected.
VoidResult error_void(int code, const std::string &message, const std::string &source="network_system", const std::string &details="")
Callback functions for connection events.
Configuration options for connections.
Network endpoint information (host/port or URL)