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

Last change on this file since 16562 was 16090, checked in by tbretz, 12 years ago
Replaced queue by list; added Connection::IsTxQueueEmpty
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 std::list<std::vector<char>> fOutQueue;
42
43 ConnectionStatus_t fConnectionStatus;
44
45 std::string fErrConnect;
46 std::string fMsgConnect;
47
48public:
49 void SetLogStream(MessageImp *log) { fLog = log; }
50 std::ostream &Out() { return fLog ? fLog->Out() : Out(); }
51
52 // -------- Abbreviations for starting async tasks ---------
53
54 void AsyncRead(const boost::asio::mutable_buffers_1 buffers, int type=0);
55 void AsyncWrite(const boost::asio::const_buffers_1 &buffers);
56
57 template<class T>
58 void AsyncWaitImp(boost::asio::deadline_timer &timer, int millisec,
59 void (T::*handler)(const boost::system::error_code&))
60 {
61 // - The boost::asio::basic_deadline_timer::expires_from_now()
62 // function cancels any pending asynchronous waits, and returns
63 // the number of asynchronous waits that were cancelled. If it
64 // returns 0 then you were too late and the wait handler has
65 // already been executed, or will soon be executed. If it
66 // returns 1 then the wait handler was successfully cancelled.
67 // - If a wait handler is cancelled, the bs::error_code passed to
68 // it contains the value bs::error::operation_aborted.
69 timer.expires_from_now(boost::posix_time::milliseconds(millisec));
70
71 timer.async_wait(boost::bind(handler, this, boost::asio::placeholders::error));
72 }
73
74 void AsyncWait(boost::asio::deadline_timer &timer, int millisec,
75 void (Connection::*handler)(const boost::system::error_code&))
76 {
77 AsyncWaitImp(timer, millisec, handler);
78 }
79
80
81private:
82 void AsyncConnect(boost::asio::ip::tcp::resolver::iterator iterator);
83 void AsyncConnect();
84
85 void CloseImp(bool restart=true);
86
87 bool ConnectImp(const boost::asio::ip::tcp::endpoint &endpoint,
88 const boost::system::error_code& error);
89 void ConnectIter(boost::asio::ip::tcp::resolver::iterator endpoint_iterator,
90 const boost::system::error_code& error);
91 void ConnectAddr(const boost::asio::ip::tcp::endpoint &endpoint,
92 const boost::system::error_code& error);
93
94 void HandleConnectionTimer(const boost::system::error_code &error);
95 void HandleWriteTimeout(const boost::system::error_code &error);
96 void HandleSentData(const boost::system::error_code& error, size_t);
97
98 int Write(const Time &t, const std::string &txt, int qos=kInfo);
99
100 virtual void ConnectionEstablished() { }
101
102public:
103 Connection(boost::asio::io_service& io_service, std::ostream &out);
104
105 // ------------------------ connect --------------------------
106
107 void SetEndpoint(const std::string &addr, int port);
108 void SetEndpoint(const std::string &addr, const std::string &port);
109 void SetEndpoint(const std::string &addr);
110 void SetEndpoint(const boost::asio::ip::tcp::endpoint &ep);
111
112 void StartConnect();
113
114 // ------------------------ close --------------------------
115 void PostClose(bool restart=true);
116
117 // ------------------------ write --------------------------
118 void SendMessageImp(const std::vector<char> msg);
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 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.