IRSOL
C++ code implementing socket server for interacting with Baumer camera.
irsol::server::internal::ClientSessionAcceptor Class Reference

Accepts incoming TCP connections and triggers a callback for each new client. More...

#include <acceptor.hpp>

Public Member Functions

 ClientSessionAcceptor (irsol::types::port_t port, OnNewClientCallback_t onNewClientCallback)
 Constructs the acceptor.
 
void run ()
 Starts the accept loop.
 
void stop ()
 Stops the accept loop.
 
std::string error () const
 Gets the current error message, if any.
 
bool isOpen () const
 Checks if the acceptor is actively listening.
 

Private Attributes

std::atomic< bool > m_running {false}
 Flag indicating whether the acceptor should continue running.
 
const irsol::types::port_t m_port
 Port on which to accept incoming TCP connections.
 
OnNewClientCallback_t m_onNewClientCallback
 Callback to handle accepted client connections.
 
irsol::types::acceptor_t m_acceptor
 TCP acceptor socket bound to m_port.
 
irsol::types::connection_result_t m_isOpen {}
 Result of attempting to bind and open the acceptor socket.
 

Detailed Description

Accepts incoming TCP connections and triggers a callback for each new client.

The ClientSessionAcceptor listens on a given TCP port and forwards each accepted socket to the provided callback, enabling session initialization for each client.

Definition at line 48 of file acceptor.hpp.

Constructor & Destructor Documentation

◆ ClientSessionAcceptor()

irsol::server::internal::ClientSessionAcceptor::ClientSessionAcceptor ( irsol::types::port_t  port,
OnNewClientCallback_t  onNewClientCallback 
)

Constructs the acceptor.

Parameters
portTCP port to bind and listen on.
onNewClientCallbackFunction to call when a new client connects.

Definition at line 11 of file acceptor.cpp.

14 : m_port(port), m_onNewClientCallback(onNewClientCallback)
15{
17}
OnNewClientCallback_t m_onNewClientCallback
Callback to handle accepted client connections.
Definition acceptor.hpp:103
const irsol::types::port_t m_port
Port on which to accept incoming TCP connections.
Definition acceptor.hpp:98
irsol::types::acceptor_t m_acceptor
TCP acceptor socket bound to m_port.
Definition acceptor.hpp:108
irsol::types::connection_result_t m_isOpen
Result of attempting to bind and open the acceptor socket.
Definition acceptor.hpp:113
sockpp::inet_address inet_address_t
Alias for an IPv4/IPv6 internet address.
Definition types.hpp:79

Member Function Documentation

◆ error()

std::string irsol::server::internal::ClientSessionAcceptor::error ( ) const

Gets the current error message, if any.

Returns
A string describing the most recent error that might have been raised while trying to bind to the TCP port.
Exceptions
irsol::AssertionExceptionin case the acceptor it not in error mode.

Definition at line 20 of file acceptor.cpp.

21{
22 IRSOL_ASSERT_ERROR(!isOpen(), "Acceptor is not in error mode");
23 return m_isOpen.error().message();
24}
bool isOpen() const
Checks if the acceptor is actively listening.
Definition acceptor.cpp:27
#define IRSOL_ASSERT_ERROR
Error-level assertion macro.
Definition assert.hpp:134

◆ isOpen()

bool irsol::server::internal::ClientSessionAcceptor::isOpen ( ) const

Checks if the acceptor is actively listening.

Returns
True if the socket is open and accepting connections.

Definition at line 27 of file acceptor.cpp.

28{
29 return bool(m_isOpen);
30}

◆ run()

void irsol::server::internal::ClientSessionAcceptor::run ( )

Starts the accept loop.

This method enters a blocking loop accepting client connections and invoking the callback for each. It is typically run in a dedicated thread.

Definition at line 44 of file acceptor.cpp.

45{
46 if(!isOpen()) {
47 IRSOL_LOG_ERROR("Failed to open acceptor on port {}: {}", m_port, error());
48 throw std::runtime_error("Failed to open acceptor");
49 }
50 if(m_running) {
51 IRSOL_LOG_ERROR("Accept loop already running");
52 return;
53 }
54 m_running.store(true);
55
56 IRSOL_LOG_INFO("Accept loop started");
57 while(m_running) {
58
59 // Set non-blocking mode to avoid blocking indefinitely on accept
60 m_acceptor.set_non_blocking(true);
61
62 auto sockResult = m_acceptor.accept();
63
64 // Check if we should exit the loop
65 if(!m_running) {
66 IRSOL_LOG_DEBUG("Accept loop stopped");
67 break;
68 }
69
70 if(!sockResult) {
71 if(m_running) {
72 sockpp::error_code err{sockResult.error()};
73 // These errors are expected in non-blocking mode when no connection is available
74 bool isExpectedError =
75 (err == std::errc::resource_unavailable_try_again ||
76 err == std::errc::operation_would_block || err == std::errc::timed_out);
77
78 if(isExpectedError) {
79 // Sleep for a short time to avoid busy waiting when no connections are available
80 std::this_thread::sleep_for(std::chrono::milliseconds(1000));
81 } else {
82 // Log unexpected errors
83 IRSOL_LOG_WARN("Failed to accept connection: {}", sockResult.error_message());
84 }
85 }
86 continue;
87 }
88
89 // Generate a unique ID for this client session
91 IRSOL_LOG_DEBUG("Generated client ID: {}", clientId);
92 m_onNewClientCallback(clientId, sockResult.release());
93 }
94 IRSOL_LOG_INFO("Accept loop ended");
95}
std::atomic< bool > m_running
Flag indicating whether the acceptor should continue running.
Definition acceptor.hpp:93
std::string error() const
Gets the current error message, if any.
Definition acceptor.cpp:20
#define IRSOL_LOG_INFO(...)
Logs an info-level message using the default logger.
Definition logging.hpp:92
#define IRSOL_LOG_ERROR(...)
Logs an error-level message using the default logger.
Definition logging.hpp:94
#define IRSOL_LOG_WARN(...)
Logs a warning-level message using the default logger.
Definition logging.hpp:93
#define IRSOL_LOG_DEBUG(...)
Logs a debug-level message using the default logger.
Definition logging.hpp:91
std::string client_id_t
Represents a unique client identifier. Typically used to identify connected clients by string IDs.
Definition types.hpp:55
std::string uuid()
Generates a new UUID string.
Definition utils.cpp:16

◆ stop()

void irsol::server::internal::ClientSessionAcceptor::stop ( )

Stops the accept loop.

Calling this method will cause run() to return and stop accepting new connections.

Definition at line 33 of file acceptor.cpp.

34{
35 if(!m_running) {
36 IRSOL_LOG_DEBUG("Accept loop already stopped");
37 return;
38 }
39 m_running.store(false);
40 m_acceptor.close();
41}

Member Data Documentation

◆ m_acceptor

irsol::types::acceptor_t irsol::server::internal::ClientSessionAcceptor::m_acceptor
private

TCP acceptor socket bound to m_port.

Definition at line 108 of file acceptor.hpp.

◆ m_isOpen

irsol::types::connection_result_t irsol::server::internal::ClientSessionAcceptor::m_isOpen {}
private

Result of attempting to bind and open the acceptor socket.

Definition at line 113 of file acceptor.hpp.

113{};

◆ m_onNewClientCallback

OnNewClientCallback_t irsol::server::internal::ClientSessionAcceptor::m_onNewClientCallback
private

Callback to handle accepted client connections.

Definition at line 103 of file acceptor.hpp.

◆ m_port

const irsol::types::port_t irsol::server::internal::ClientSessionAcceptor::m_port
private

Port on which to accept incoming TCP connections.

Definition at line 98 of file acceptor.hpp.

◆ m_running

std::atomic<bool> irsol::server::internal::ClientSessionAcceptor::m_running {false}
private

Flag indicating whether the acceptor should continue running.

Note
This is usually set by the irsol::server::App (or the main thread that manages the acceptor thread) for shut-down operations.

Definition at line 93 of file acceptor.hpp.

93{false};

The documentation for this class was generated from the following files: