This class provides connection to another agentXcpp entity via a unix domain socket. More...
#include <connector.hpp>
Classes | |
| class | pdu_handler |
| Interface for classes which can handle incoming PDU's. More... | |
Public Member Functions | |
| connector (boost::shared_ptr< boost::asio::io_service > io_service, const std::string &unix_domain_socket, unsigned timeout) | |
| The constructor. | |
| boost::shared_ptr< ResponsePDU > | wait_for_response (uint32_t packetID) |
| Wait with timeout for a reponse. | |
| void | register_handler (pdu_handler *) |
| Register a handler object for received PDU's. | |
| void | connect () |
| Connect to the remote entity. | |
| void | disconnect () |
| Disconnect the remote entity. | |
| bool | is_connected () |
| Find out whether the object is currently connected. | |
| void | send (const PDU &pdu) |
| send a PDU to the remote entity. | |
| ~connector () | |
| Destructor. | |
Private Member Functions | |
| void | receive_callback (const boost::system::error_code &result) |
| Callback function to receive a PDU. | |
| connector () | |
| Hide standard constructor. | |
Private Attributes | |
| unsigned | timeout |
| The timeout in milliseconds, used in various contexts. | |
| boost::shared_ptr < boost::asio::io_service > | io_service |
| The mandatory io_service object. | |
| boost::asio::local::stream_protocol::socket * | socket |
| The socket. | |
| boost::asio::local::stream_protocol::endpoint | endpoint |
| The endpoint used for unix domain sockets. | |
| std::map< uint32_t, boost::shared_ptr< ResponsePDU > > | responses |
| The received, yet unprocessed ReponsePDU's. | |
| byte_t | header_buf [20] |
| Buffer to receive a PDU header. | |
| pdu_handler * | handler |
| The handler object for incoming PDU's. | |
This class provides connection to another agentXcpp entity via a unix domain socket.
A connector object is always in one of the following states:
When created, a connector object starts in disconnected state. The current state can be obtained using the is_connected() method. Some operations may throw a disconnected exception if the object is in disconnected state. Further, the connection may fail at any point in time, therefore a disconnected exception may also be thrown during a network operation.
The socket needed for networking is created upon connect and destroyed upon disconnect. The reason is that closing the socket may throw a system_error exception, leaving the socket in an unknown state. Destroying it and creating a new one should be safe.
Sending works as follows:
Note: The send() function invokes io_service->run_one() one or several times.
Receiving PDU's works as follows:
The function wait_for_response() supports the request-response communication model. After sending a request to the remote entity (using send()), wait_for_response() is used to wait for the response. It blocks while waiting for a responsePDU from the remote entity, which is then returned to the caller. The wait_for_response() function may seem to do synchronous operations only, but this is not true. In fact, it uses an asynchronous receive mechanism, because there may be other PDU's in the queue before the given response is actually received. wait_for_response() therefore invokes io_service->run_one() one ore more times, until the response is received. This may also cause other asynchronous operations to finish. For example, the registered handler object may receive other PDU types, or another asynchronous operation on the io_service object (outside this class or even outside the agentXcpp library) may be served. Here are the steps performed to receive a ResponsePDU:
The same timeout value is used by all operations which deal with timeouts. The value is stored in the timeout member.
Definition at line 127 of file connector.hpp.
| agentxcpp::connector::connector | ( | ) | [private] |
Hide standard constructor.
We need an io_service object to function properly.
| connector::connector | ( | boost::shared_ptr< boost::asio::io_service > | io_service, |
| const std::string & | unix_domain_socket, | ||
| unsigned | timeout | ||
| ) |
The constructor.
This constructor initializes the connector object to be in disconnected state.
| io_service | The io_service object needed for boost::asio operations. It may also be used by other parts of the program. |
| unix_domain_socket | The path to the unix_domain_socket. |
| timeout | The timeout, in milliseconds, for sending and receiving PDU's. See the documentation of the respective methods for details. |
| None. |
Definition at line 410 of file connector.cpp.
| agentxcpp::connector::~connector | ( | ) | [inline] |
Destructor.
| None. |
Definition at line 398 of file connector.hpp.
References disconnect().
| void connector::connect | ( | ) |
Connect to the remote entity.
This function connects to the remote entity and starts receiving PDU's. If the object is already connected, the function does nothing.
| disconnected | If connecting fails. |
Definition at line 421 of file connector.cpp.
References endpoint, header_buf, io_service, receive_callback(), and socket.
Referenced by agentxcpp::master_proxy::connect(), and agentxcpp::master_proxy::reconnect().
| void connector::disconnect | ( | ) |
Disconnect the remote entity.
Stops receiving PDU's and disconnects the remote entity.
| None. |
Definition at line 454 of file connector.cpp.
References socket.
Referenced by agentxcpp::master_proxy::connect(), agentxcpp::master_proxy::disconnect(), receive_callback(), agentxcpp::master_proxy::reconnect(), send(), wait_for_response(), and ~connector().
| bool agentxcpp::connector::is_connected | ( | ) | [inline] |
Find out whether the object is currently connected.
| None. |
Definition at line 363 of file connector.hpp.
References socket.
Referenced by agentxcpp::master_proxy::connect(), agentxcpp::master_proxy::disconnect(), and agentxcpp::master_proxy::is_connected().
| void connector::receive_callback | ( | const boost::system::error_code & | result | ) | [private] |
Callback function to receive a PDU.
See the class documentation to learn about the receive mechanism.
The synchronous read operation (to read the payload) may time out, using the class' timeout value. If the read times out, the socket is destroyed and the connector object becomes disconnected.
| result | The result of the asynchronous read operation (provided by boost::asio). |
| None. |
Definition at line 502 of file connector.cpp.
References disconnect(), agentxcpp::connector::pdu_handler::handle_pdu(), handler, header_buf, agentxcpp::PDU::parse_pdu(), read32(), responses, and socket.
Referenced by connect().
| void connector::register_handler | ( | pdu_handler * | handler | ) |
Register a handler object for received PDU's.
Every time a PDU is received, the handler object's handle_pdu() method will be invoked with the PDU as argument. This method is executed in the context of the io_service object's run() or run_one() method. Care should be taken to not block the call, e.g. by doing networking.
After registering a handler it can be unregistered again by calling this function with a null pointer. While no handler object is registered, received PDU's are silently discarded.
| handler | A pointer to the handler object, or null. |
| None. |
Definition at line 496 of file connector.cpp.
References handler.
Referenced by agentxcpp::master_proxy::master_proxy().
| void connector::send | ( | const PDU & | pdu | ) |
send a PDU to the remote entity.
The PDU is sent to the remote entity. If the timeout expires during the send operation, a timeout_error is thrown and the object gets disconnected.
| pdu | The PDU to send |
| timeout_error | If a timeout error occurs. The function uses the timeout value given during construction. The objects gets disconnected in this case. Some data might be sent already. |
| disconnected | If disconnected. This is also thrown if sending fails and the object gets disconnected for that reason. Some data might be sent already. |
Definition at line 629 of file connector.cpp.
References disconnect(), agentxcpp::PDU::serialize(), and socket.
Referenced by agentxcpp::master_proxy::connect(), agentxcpp::master_proxy::disconnect(), agentxcpp::master_proxy::do_registration(), and agentxcpp::master_proxy::undo_registration().
| boost::shared_ptr< ResponsePDU > connector::wait_for_response | ( | uint32_t | packetID | ) |
Wait with timeout for a reponse.
This function blocks until a ResponsePDU with the given packetID is received or until the timeout expires, whichever comes first. The received ResponsePDU (if any) is returned.
This function calls run_one() repeatedly on the io_service object until the desired ResponsePDU arrives or the timeout expires. This may cause other asynchronous operations to be served, as well.
| packetID | The packetID to wait for. |
| timeout_exception | If the timeout expired before the ResponsePDU was received. The connector object stays in connected state. |
| disconnected | If disconnected. This is also thrown if the operation fails and the object gets disconnected for that reason. |
Definition at line 697 of file connector.cpp.
References disconnect(), in_progress, io_service, responses, and socket.
Referenced by agentxcpp::master_proxy::connect(), agentxcpp::master_proxy::disconnect(), agentxcpp::master_proxy::do_registration(), and agentxcpp::master_proxy::undo_registration().
boost::asio::local::stream_protocol::endpoint agentxcpp::connector::endpoint [private] |
The endpoint used for unix domain sockets.
Definition at line 178 of file connector.hpp.
Referenced by connect().
pdu_handler* agentxcpp::connector::handler [private] |
The handler object for incoming PDU's.
This handler object is informed by receive_callback() for each received PDU (except ResponsePDU's).
The pointer may be null, which means that there is no handler object registered.
Definition at line 247 of file connector.hpp.
Referenced by receive_callback(), and register_handler().
byte_t agentxcpp::connector::header_buf[20] [private] |
Buffer to receive a PDU header.
See the class documentation to learn about the receive mechanism.
The PDU header is placed here before receive_callback() is called by boost::asio.
Since the AgentX-header is always 20 bytes in length, this buffer is 20 bytes in size.
Definition at line 236 of file connector.hpp.
Referenced by connect(), and receive_callback().
boost::shared_ptr<boost::asio::io_service> agentxcpp::connector::io_service [private] |
The mandatory io_service object.
This object is needed for boost::asio sockets. It is provided by the user of this class.
Definition at line 166 of file connector.hpp.
Referenced by connect(), and wait_for_response().
std::map< uint32_t, boost::shared_ptr<ResponsePDU> > agentxcpp::connector::responses [private] |
The received, yet unprocessed ReponsePDU's.
See the class documentation to learn about the receive mechanism.
The wait_for_response() function stores a null pointer to this map to indicate that it is waiting for a certain response.
When a response is received, the receive_callback() function stores it into the map, but only if a null pointer is found for the packetID of the received ResponsePDU. Otherwise, the received ResponsePDU is discarded.
After a ResponsePDU was received and stored into the map, the wait_for_response() function processes it and erases it from the map.
The map key is the packetID of the response which is awaited.
Definition at line 221 of file connector.hpp.
Referenced by receive_callback(), and wait_for_response().
boost::asio::local::stream_protocol::socket* agentxcpp::connector::socket [private] |
The socket.
The null pointer while disconnected.
Definition at line 173 of file connector.hpp.
Referenced by connect(), disconnect(), is_connected(), receive_callback(), send(), and wait_for_response().
unsigned agentxcpp::connector::timeout [private] |
The timeout in milliseconds, used in various contexts.
Definition at line 158 of file connector.hpp.