2#ifndef _KURLYK_BASE_WEB_SOCKET_CLIENT_HPP_INCLUDED
3#define _KURLYK_BASE_WEB_SOCKET_CLIENT_HPP_INCLUDED
30 std::function<void(std::unique_ptr<WebSocketEventData>)>&
event_handler() override final {
46 void set_config(std::unique_ptr<WebSocketConfig> config, std::function<
void(
bool)> callback)
override final {
52 void connect(std::function<
void(
bool)> callback)
override final {
58 void disconnect(std::function<
void(
bool)> callback)
override final {
78 std::list<std::unique_ptr<WebSocketEventData>>
receive_events() const override final {
89 std::unique_ptr<WebSocketEventData>
receive_event() const override final {
92 std::unique_ptr<WebSocketEventData>
event = std::move(*
m_event_queue.begin());
103 const std::string &message,
105 std::function<
void(
const std::error_code& ec)> callback =
nullptr) override final {
106 if (message.empty()) {
117# if __cplusplus >= 201402L
118 m_message_queue.push_back(std::make_shared<WebSocketSendInfo>(message, rate_limit_id,
false, 0, std::move(callback)));
131 const std::string &message,
133 std::function<
void(
const std::error_code& ec)> callback =
nullptr) override final {
143 const int status = 1000,
144 const std::string &reason = std::string(),
145 std::function<
void(
const std::error_code& ec)> callback =
nullptr) override final {
154# if __cplusplus >= 201402L
155 m_message_queue.push_back(std::make_shared<WebSocketSendInfo>(reason, 0,
true, status, std::move(callback)));
168 const int status = 1000,
169 const std::string &reason = std::string(),
170 std::function<
void(
const std::error_code& ec)> callback =
nullptr) override final {
228 virtual void send_message(std::shared_ptr<WebSocketSendInfo>& send_info) = 0;
232 virtual void send_close(std::shared_ptr<WebSocketSendInfo>& send_info) = 0;
237# if __cplusplus >= 201402L
238 auto event = std::make_unique<WebSocketEventData>();
242 event->sender = shared_from_this();
253 const std::string& reason =
"Normal Closure",
254 int status_code = 1000) {
257 websocket_event->message = reason;
258 websocket_event->status_code = status_code;
259 return websocket_event;
268 const std::error_code& error_code) {
271 websocket_event->error_code = error_code;
272 return websocket_event;
279 const std::error_code& error_code,
280 const std::function<
void(
const std::error_code& ec)> &callback) {
295 std::function<void(std::unique_ptr<WebSocketEventData>)>
m_on_event;
312 callback(std::move(other.callback)) {
319 if (
this != &other) {
323 callback = std::move(other.callback);
339 std::unique_ptr<WebSocketEventData> &&
event_data) :
351 std::function<
void(
bool)> &&
callback) :
362 std::function<
void(
bool)> &&
callback) :
393 using send_callback_t = std::pair<std::error_code, std::function<void(
const std::error_code& ec)>>;
422 switch (event.event_type) {
426 if (event.callback)
event.callback(
false);
432 if (event.callback)
event.callback(
false);
437 if (event.callback)
event.callback(
true);
441 m_config = std::move(event.config_data);
445 if (event.callback)
event.callback(
true);
447 if (event.callback)
event.callback(
false);
451 if (event.callback)
event.callback(
false);
461 switch (event.event_type) {
495 if (event.callback)
event.callback(
true);
503 m_config = std::move(event.config_data);
506 if (event.callback)
event.callback(
false);
516 if (event.callback)
event.callback(
false);
522 if (event.callback)
event.callback(
true);
526 if (event.callback)
event.callback(
false);
537 switch (event.event_type) {
544 if (event.callback)
event.callback(
true);
572 m_config = std::move(event.config_data);
575 if (event.callback)
event.callback(
false);
585 if (event.callback)
event.callback(
false);
591 if (event.callback)
event.callback(
true);
599 if (event.callback)
event.callback(
false);
602 if (!is_message)
break;
610 switch (event.event_type) {
613 if (event.callback)
event.callback(
true);
617 m_config = std::move(event.config_data);
620 if (event.callback)
event.callback(
false);
630 if (event.callback)
event.callback(
false);
636 if (event.callback)
event.callback(
true);
643 if (event.callback)
event.callback(
false);
662 auto now = std::chrono::steady_clock::now();
663 auto duration = std::chrono::duration_cast<std::chrono::seconds>(now -
m_close_time);
664 if (duration.count() >=
m_config->reconnect_delay) {
685 switch (event.event_type) {
689 if (event.callback)
event.callback(
false);
695 if (event.callback)
event.callback(
false);
700 if (event.callback)
event.callback(
true);
704 m_config = std::move(event.config_data);
707 if (event.callback)
event.callback(
false);
717 if (event.callback)
event.callback(
false);
723 if (event.callback)
event.callback(
true);
727 if (event.callback)
event.callback(
false);
739 std::list<send_info_ptr_t> message_queue;
742 auto& send_info = *it;
748 message_queue.push_back(std::move(send_info));
752 if (message_queue.empty())
return;
754 for (
auto &send_info : message_queue) {
755 if (!send_info->is_send_close) {
772 for (
auto &item : send_callback_queue) {
773 item.second(item.first);
Defines a legacy internal interface for WebSocket client functionality.
Defines the public sender abstraction exposed through WebSocket events.
Defines the WebSocketEventData class, which encapsulates data related to WebSocket events.
Defines WebSocket rate limiting to control the frequency of WebSocket requests.
virtual ~BaseWebSocketClient()=default
Virtual destructor.
void process_state_working()
Handles the WORKING state. Processes incoming events and manages connection health.
std::chrono::steady_clock::time_point m_close_time
Timestamp of the last WebSocket close event, used for reconnection timing.
virtual bool init_websocket()=0
Initializes the WebSocket connection. Must be implemented in derived classes.
void handle_message_event(std::unique_ptr< WebSocketEventData > event)
Handles incoming WebSocket message events and queues them if no event handler is set.
bool send_message(const std::string &message, long rate_limit_id, std::function< void(const std::error_code &ec)> callback=nullptr) override final
Sends a message through the WebSocket.
std::unique_ptr< WebSocketEventData > event_data_ptr_t
Alias for unique pointers to WebSocketEventData.
std::unique_ptr< WebSocketEventData > create_websocket_event()
Creates a generic WebSocket event.
BaseWebSocketClient()=default
Default constructor.
bool is_connected() const override final
Checks if the WebSocket client is actively running.
void connect(std::function< void(bool)> callback) override final
Initiates a connection to the WebSocket server.
std::mutex m_message_queue_mutex
Mutex for synchronizing access to the message queue.
std::mutex m_send_callback_queue_mutex
Mutex for synchronizing access to the send callback queue.
std::mutex m_event_queue_mutex
Mutex for synchronizing access to the event queue.
bool is_running() const override final
Checks if the WebSocket client is actively running.
void process_state_connecting()
Handles the CONNECTING state. Manages connection attempt, errors, or disconnection.
void process_state_init()
Handles the INIT state. Initializes connection or updates configuration.
enum kurlyk::BaseWebSocketClient::FsmState m_fsm_state
SubmitResult submit_message(const std::string &message, long rate_limit_id, std::function< void(const std::error_code &ec)> callback=nullptr) override final
Attempts to submit a message through the WebSocket.
bool send_close(const int status=1000, const std::string &reason=std::string(), std::function< void(const std::error_code &ec)> callback=nullptr) override final
Sends a close request through the WebSocket.
void handle_error_event(const std::error_code &error_code)
Overloaded method to handle WebSocket error events using an error code.
WebSocketRateLimiter m_rate_limiter
Rate limiter for controlling the frequency of message sending.
utils::EventQueue< FSMEventData > m_fsm_event_queue
Queue for FSM events, managing the event sequence for the FSM.
void handle_close_event(std::unique_ptr< WebSocketEventData > event=nullptr)
Handles the event when the WebSocket connection is closed.
virtual void deinit_websocket()=0
Deinitializes the WebSocket connection. Must be implemented in derived classes.
void process_state_stopped()
Processes the STOPPED state in the FSM.
std::list< event_data_ptr_t > m_event_queue
Queue holding pending WebSocket events.
std::unique_ptr< WebSocketEventData > create_websocket_close_event(const std::string &reason="Normal Closure", int status_code=1000)
Creates a WebSocket close event with a specified reason and status code.
std::pair< std::error_code, std::function< void(const std::error_code &ec)> > send_callback_t
Alias for callback pairs with error codes.
void set_config(std::unique_ptr< WebSocketConfig > config, std::function< void(bool)> callback) override final
Sets the configuration for the WebSocket client.
void handle_error_event(std::unique_ptr< WebSocketEventData > event)
Handles WebSocket error events and queues them if no event handler is set.
void process_message_queue()
Processes the queue of messages to be sent over the WebSocket.
virtual void send_message(std::shared_ptr< WebSocketSendInfo > &send_info)=0
Sends a WebSocket message.
std::unique_ptr< WebSocketEventData > receive_event() const override final
Retrieves the next available WebSocket event, if any.
FsmState
Finite State Machine (FSM) states for the WebSocket connection.
@ WORKING
Connection active and working.
@ CONNECTING
Awaiting connection.
@ RECONNECTING
Reconnection attempt.
@ INIT
Initialization state.
void process_fsm_state()
Processes the current FSM state and transitions to the appropriate next state.
std::function< void(std::unique_ptr< WebSocketEventData >)> m_on_event
Function to handle WebSocket events. Called when a new event is received.
std::list< std::unique_ptr< WebSocketEventData > > receive_events() const override final
Retrieves all pending WebSocket events in a batch.
void process_send_callback_queue()
Processes the queue of send callbacks.
std::function< void(std::unique_ptr< WebSocketEventData >)> & event_handler() override final
Accessor for the event handler function.
void process_state_reconnecting()
Handles the RECONNECTING state. Attempts to reconnect based on configuration settings.
void add_send_callback(const std::error_code &error_code, const std::function< void(const std::error_code &ec)> &callback)
Adds a send callback to the queue.
std::atomic< bool > m_is_connected
Atomic flag indicating if the client is connected.
void process() override final
Processes internal operations such as event handling and state updates.
std::atomic< std::size_t > m_max_send_queue_size
Maximum number of queued outbound send operations, or zero if unbounded.
SubmitResult submit_close(const int status=1000, const std::string &reason=std::string(), std::function< void(const std::error_code &ec)> callback=nullptr) override final
Attempts to submit a close request through the WebSocket.
void disconnect(std::function< void(bool)> callback) override final
Closes the connection to the WebSocket server.
std::list< send_callback_t > m_send_callback_queue
Queue holding send callbacks with their respective error codes.
void add_fsm_event(FsmEvent event_type, std::unique_ptr< WebSocketEventData > event_data)
Adds an FSM event to the event queue and triggers the notify handler.
std::unique_ptr< WebSocketConfig > m_config
Current configuration for the WebSocket.
std::shared_ptr< WebSocketSendInfo > send_info_ptr_t
Alias for shared pointers to WebSocketSendInfo.
FsmEvent
Represents events in the finite state machine.
@ ConnectionError
Error in connection.
@ UpdateConfig
Update configuration.
@ ConnectionClosed
Connection closed.
@ RequestConnect
Request to connect.
@ MessageReceived
Incoming WebSocket message.
@ RequestDisconnect
Request to disconnect.
@ ConnectionOpened
Connection opened successfully.
std::function< void()> & notify_handler() override final
Accesses the notification handler for WebSocket events.
std::list< send_info_ptr_t > m_message_queue
Queue holding messages to be sent over the WebSocket.
virtual void send_close(std::shared_ptr< WebSocketSendInfo > &send_info)=0
Sends a close request.
std::unique_ptr< WebSocketEventData > create_websocket_error_event(const std::error_code &error_code)
Creates a WebSocket error event with a specified error code.
long m_reconnect_attempt
Counter for the number of reconnection attempts.
std::atomic< bool > m_is_running
Atomic flag indicating if the client is running.
std::function< void()> m_on_event_notify
Function to notify about new events in the FSM.
void handle_open_event(std::unique_ptr< WebSocketEventData > event)
Handles the event when the WebSocket connection is opened.
void shutdown() override final
Shuts down the WebSocket client, disconnecting and clearing all pending events.
IWebSocketClient()=default
Default constructor.
Encapsulates data for a WebSocket event, providing information about event type, message,...
Manages rate limiting for WebSocket requests based on predefined limits.
Holds information for sending a WebSocket message, including rate limiting, close status,...
A thread-safe event queue that supports blocking and non-blocking event retrieval.
@ NotConnected
Operation requires an active connection but none exists.
@ QueueLimitExceeded
Operation was rejected because the bounded queue is already full.
@ InvalidConfiguration
Provided configuration is incomplete or invalid.
std::error_code make_error_code(ClientError e)
Creates a std::error_code from a ClientError value.
Primary namespace for the Kurlyk library, encompassing initialization, request management,...
@ WS_ERROR
Error occurred.
@ WS_CLOSE
Connection closed.
Enables use of ClientError with std::error_code.
Represents an event in the finite state machine (FSM) with optional associated data and callback.
std::function< void(bool)> callback
Optional callback function to execute on event completion.
FSMEventData & operator=(const FSMEventData &)=delete
Deleted copy assignment operator to prevent copying.
FSMEventData(FsmEvent event_type, std::unique_ptr< WebSocketEventData > &&event_data)
Constructs FSMEventData with an event type and WebSocket event data.
FSMEventData(const FSMEventData &)=delete
Deleted copy constructor to prevent copying.
std::unique_ptr< WebSocketEventData > event_data
Optional WebSocket event data associated with the FSM event.
FSMEventData(FsmEvent event_type)
Constructs FSMEventData with only an event type.
FSMEventData(FSMEventData &&other) noexcept
Move constructor for FSMEventData.
FSMEventData(FsmEvent event_type, std::function< void(bool)> &&callback)
Constructs FSMEventData with an event type and a callback.
FSMEventData & operator=(FSMEventData &&other) noexcept
Move assignment operator for FSMEventData.
FSMEventData(FsmEvent event_type, std::unique_ptr< WebSocketConfig > &&config_data, std::function< void(bool)> &&callback)
Constructs FSMEventData with an event type, configuration data, and a callback.
FsmEvent event_type
The type of the FSM event.
std::unique_ptr< WebSocketConfig > config_data
Optional configuration data for FSM settings.
Represents the synchronous result of trying to enqueue or submit work.
bool accepted
Indicates whether the work item was accepted for processing.