source: trunk/FACT++/src/Connection.h@ 16814

Last change on this file since 16814 was 16769, checked in by tbretz, 11 years ago
There is no need to make the scheduling of the async write asynchronously, so I schedule the async write now directly; this also removed the send queue, which was primarily introduced to make the tranmission to the FTM serial, but this is not needed anymore; to keep track of the send queue size and for debugging, a counter for the messages in the send buffer has been introduced
File size: 5.0 KB
Line 
1#ifndef FACT_Connection
2#define FACT_Connection
3
4#include <list>
5#include <array>
6#include <string>
7
8#include <boost/bind.hpp>
9#include <boost/asio.hpp>
10#include <boost/function.hpp>
11#include <boost/asio/deadline_timer.hpp>
12
13#include "MessageImp.h"
14
15class Connection : public MessageImp, public boost::asio::ip::tcp::socket
16{
17private:
18 MessageImp *fLog;
19
20 std::string fAddress;
21 std::string fPort;
22
23 boost::asio::ip::tcp::endpoint fEndpoint;
24
25 bool fVerbose;
26 bool fDebugTx;
27
28 enum ConnectionStatus_t
29 {
30 kDisconnected = 0,
31 kConnecting = 1,
32 kConnected = 2,
33 };
34
35protected:
36 boost::asio::deadline_timer fInTimeout;
37
38private:
39 boost::asio::deadline_timer fOutTimeout;
40 boost::asio::deadline_timer fConnectionTimer;
41
42 size_t fQueueSize;
43
44 ConnectionStatus_t fConnectionStatus;
45
46 std::string fErrConnect;
47 std::string fMsgConnect;
48
49public:
50 void SetLogStream(MessageImp *log) { fLog = log; }
51 std::ostream &Out() { return fLog ? fLog->Out() : Out(); }
52
53 // -------- Abbreviations for starting async tasks ---------
54
55 void AsyncRead(const boost::asio::mutable_buffers_1 buffers, int type=0);
56 void AsyncWrite(const boost::asio::const_buffers_1 &buffers);
57
58 template<class T>
59 void AsyncWaitImp(boost::asio::deadline_timer &timer, int millisec,
60 void (T::*handler)(const boost::system::error_code&))
61 {
62 // - The boost::asio::basic_deadline_timer::expires_from_now()
63 // function cancels any pending asynchronous waits, and returns
64 // the number of asynchronous waits that were cancelled. If it
65 // returns 0 then you were too late and the wait handler has
66 // already been executed, or will soon be executed. If it
67 // returns 1 then the wait handler was successfully cancelled.
68 // - If a wait handler is cancelled, the bs::error_code passed to
69 // it contains the value bs::error::operation_aborted.
70 timer.expires_from_now(boost::posix_time::milliseconds(millisec));
71
72 timer.async_wait(boost::bind(handler, this, boost::asio::placeholders::error));
73 }
74
75 void AsyncWait(boost::asio::deadline_timer &timer, int millisec,
76 void (Connection::*handler)(const boost::system::error_code&))
77 {
78 AsyncWaitImp(timer, millisec, handler);
79 }
80
81
82private:
83 void AsyncConnect(boost::asio::ip::tcp::resolver::iterator iterator);
84 void AsyncConnect();
85
86 void CloseImp(bool restart=true);
87
88 bool ConnectImp(const boost::asio::ip::tcp::endpoint &endpoint,
89 const boost::system::error_code& error);
90 void ConnectIter(boost::asio::ip::tcp::resolver::iterator endpoint_iterator,
91 const boost::system::error_code& error);
92 void ConnectAddr(const boost::asio::ip::tcp::endpoint &endpoint,
93 const boost::system::error_code& error);
94
95 void HandleConnectionTimer(const boost::system::error_code &error);
96 void HandleWriteTimeout(const boost::system::error_code &error);
97 void HandleSentData(const boost::system::error_code& error, size_t);
98
99 int Write(const Time &t, const std::string &txt, int qos=kInfo);
100
101 virtual void ConnectionEstablished() { }
102
103public:
104 Connection(boost::asio::io_service& io_service, std::ostream &out);
105
106 // ------------------------ connect --------------------------
107
108 void SetEndpoint(const std::string &addr, int port);
109 void SetEndpoint(const std::string &addr, const std::string &port);
110 void SetEndpoint(const std::string &addr);
111 void SetEndpoint(const boost::asio::ip::tcp::endpoint &ep);
112
113 void StartConnect();
114
115 // ------------------------ close --------------------------
116 void PostClose(bool restart=true);
117
118 // ------------------------ write --------------------------
119 void PostMessage(const void *msg, size_t s=0);
120 void PostMessage(const std::string &cmd, size_t s=-1);
121
122 template<typename T, size_t N>
123 void PostMessage(const std::array<T, N> &msg)
124 {
125 PostMessage(msg.begin(), msg.size()*sizeof(T));
126 }
127
128 template<typename T>
129 void PostMessage(const std::vector<T> &msg)
130 {
131 PostMessage(&msg[0], msg.size()*sizeof(T));
132 }
133
134 // ------------------------ others --------------------------
135
136 virtual void HandleReceivedData(const boost::system::error_code&, size_t, int = 0) { }
137 virtual void HandleReadTimeout(const boost::system::error_code&) { }
138
139 bool IsTxQueueEmpty() const { return fQueueSize==0; /*fOutQueue.empty();*/ }
140
141 int IsClosed() const { return !is_open(); }
142
143 bool IsDisconnected() const { return fConnectionStatus==kDisconnected; }
144 bool IsConnected() const { return fConnectionStatus==kConnected; }
145 bool IsConnecting() const { return fConnectionStatus==kConnecting; }
146
147 void SetVerbose(bool b=true) { fVerbose=b; }
148 void SetDebugTx(bool b=true) { fDebugTx=b; }
149
150 std::string URL() const { return fAddress + ":" + fPort; }
151
152 const boost::asio::ip::tcp::endpoint &GetEndpoint() const { return fEndpoint; }
153};
154
155#endif
Note: See TracBrowser for help on using the repository browser.