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 {
108# if __cplusplus >= 201402L
109 m_message_queue.push_back(std::make_shared<WebSocketSendInfo>(message, rate_limit_id,
false, 0, std::move(callback)));
122 const int status = 1000,
123 const std::string &reason = std::string(),
124 std::function<
void(
const std::error_code& ec)> callback =
nullptr) override final {
127# if __cplusplus >= 201402L
128 m_message_queue.push_back(std::make_shared<WebSocketSendInfo>(reason, 0,
true, status, std::move(callback)));
189 virtual void send_message(std::shared_ptr<WebSocketSendInfo>& send_info) = 0;
193 virtual void send_close(std::shared_ptr<WebSocketSendInfo>& send_info) = 0;
198# if __cplusplus >= 201402L
199 auto event = std::make_unique<WebSocketEventData>();
203 event->sender = shared_from_this();
214 const std::string& reason =
"Normal Closure",
215 int status_code = 1000) {
218 websocket_event->message = reason;
219 websocket_event->status_code = status_code;
220 return websocket_event;
229 const std::error_code& error_code) {
232 websocket_event->error_code = error_code;
233 return websocket_event;
240 const std::error_code& error_code,
241 const std::function<
void(
const std::error_code& ec)> &callback) {
256 std::function<void(std::unique_ptr<WebSocketEventData>)>
m_on_event;
273 callback(std::move(other.callback)) {
280 if (
this != &other) {
284 callback = std::move(other.callback);
300 std::unique_ptr<WebSocketEventData> &&
event_data) :
312 std::function<
void(
bool)> &&
callback) :
323 std::function<
void(
bool)> &&
callback) :
353 using send_callback_t = std::pair<std::error_code, std::function<void(
const std::error_code& ec)>>;
382 switch (event.event_type) {
386 if (event.callback)
event.callback(
false);
392 if (event.callback)
event.callback(
false);
397 if (event.callback)
event.callback(
true);
401 m_config = std::move(event.config_data);
404 if (event.callback)
event.callback(
true);
406 if (event.callback)
event.callback(
false);
410 if (event.callback)
event.callback(
false);
420 switch (event.event_type) {
454 if (event.callback)
event.callback(
true);
462 m_config = std::move(event.config_data);
465 if (event.callback)
event.callback(
false);
474 if (event.callback)
event.callback(
false);
480 if (event.callback)
event.callback(
true);
484 if (event.callback)
event.callback(
false);
495 switch (event.event_type) {
502 if (event.callback)
event.callback(
true);
530 m_config = std::move(event.config_data);
533 if (event.callback)
event.callback(
false);
542 if (event.callback)
event.callback(
false);
548 if (event.callback)
event.callback(
true);
556 if (event.callback)
event.callback(
false);
559 if (!is_message)
break;
567 switch (event.event_type) {
570 if (event.callback)
event.callback(
true);
574 m_config = std::move(event.config_data);
577 if (event.callback)
event.callback(
false);
586 if (event.callback)
event.callback(
false);
592 if (event.callback)
event.callback(
true);
599 if (event.callback)
event.callback(
false);
618 auto now = std::chrono::steady_clock::now();
619 auto duration = std::chrono::duration_cast<std::chrono::seconds>(now -
m_close_time);
620 if (duration.count() >=
m_config->reconnect_delay) {
641 switch (event.event_type) {
645 if (event.callback)
event.callback(
false);
651 if (event.callback)
event.callback(
false);
656 if (event.callback)
event.callback(
true);
660 m_config = std::move(event.config_data);
663 if (event.callback)
event.callback(
false);
672 if (event.callback)
event.callback(
false);
678 if (event.callback)
event.callback(
true);
682 if (event.callback)
event.callback(
false);
694 std::list<send_info_ptr_t> message_queue;
697 auto& send_info = *it;
703 message_queue.push_back(std::move(send_info));
707 if (message_queue.empty())
return;
709 for (
auto &send_info : message_queue) {
710 if (!send_info->is_send_close) {
727 for (
auto &item : send_callback_queue) {
728 item.second(item.first);
Defines an interface for WebSocket client functionality, including connection management,...
Defines the interface for a WebSocket sender, providing methods for sending messages and managing con...
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
Send 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
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
Send 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.
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.
@ 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.