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

Last change on this file since 18530 was 17917, checked in by tbretz, 10 years ago
Added a virtual function which allows the derived class to handle if a connection attemp failed.
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 virtual void ConnectionFailed() { }
103
104public:
105 Connection(boost::asio::io_service& io_service, std::ostream &out);
106
107 // ------------------------ connect --------------------------
108
109 void SetEndpoint(const std::string &addr, int port);
110 void SetEndpoint(const std::string &addr, const std::string &port);
111 void SetEndpoint(const std::string &addr);
112 void SetEndpoint(const boost::asio::ip::tcp::endpoint &ep);
113
114 virtual void StartConnect();
115
116 // ------------------------ close --------------------------
117 void PostClose(bool restart=true);
118
119 // ------------------------ write --------------------------
120 void PostMessage(const void *msg, size_t s=0);
121 void PostMessage(const std::string &cmd, size_t s=-1);
122
123 template<typename T, size_t N>
124 void PostMessage(const std::array<T, N> &msg)
125 {
126 PostMessage(msg.begin(), msg.size()*sizeof(T));
127 }
128
129 template<typename T>
130 void PostMessage(const std::vector<T> &msg)
131 {
132 PostMessage(&msg[0], msg.size()*sizeof(T));
133 }
134
135 // ------------------------ others --------------------------
136
137 virtual void HandleReceivedData(const boost::system::error_code&, size_t, int = 0) { }
138 virtual void HandleReadTimeout(const boost::system::error_code&) { }
139
140 bool IsTxQueueEmpty() const { return fQueueSize==0; /*fOutQueue.empty();*/ }
141
142 int IsClosed() const { return !is_open(); }
143
144 bool IsDisconnected() const { return fConnectionStatus==kDisconnected; }
145 bool IsConnected() const { return fConnectionStatus==kConnected; }
146 bool IsConnecting() const { return fConnectionStatus==kConnecting; }
147
148 void SetVerbose(bool b=true) { fVerbose=b; }
149 void SetDebugTx(bool b=true) { fDebugTx=b; }
150
151 std::string URL() const { return fAddress + ":" + fPort; }
152
153 const boost::asio::ip::tcp::endpoint &GetEndpoint() const { return fEndpoint; }
154};
155
156#endif
Note: See TracBrowser for help on using the repository browser.