Jpp  19.1.0-rc.1
the software that should make you happy
recipient.hh
Go to the documentation of this file.
1 #ifndef RECIPIENT_HH
2 #define RECIPIENT_HH
3 
4 #include <boost/asio.hpp>
5 #include <FrameFactory/frame.hh>
6 #include <boost/circular_buffer.hpp>
7 #include "log.hh"
8 
9 /**
10  * \author cpellegrino
11  */
12 
13 typedef boost::circular_buffer<Frame> CircularBuffer;
14 
15 class Recipient
16 {
17  boost::asio::ip::tcp::socket m_sock;
18  boost::asio::ip::tcp::endpoint m_endpoint;
21 
22  public:
23 
24  Recipient(boost::asio::io_service& service,
25  const boost::asio::ip::tcp::endpoint& endpoint,
26  size_t circbuff_size)
27  :
28  m_sock(service),
29  m_endpoint(endpoint),
30  m_cbuffer(circbuff_size),
31  m_connected(false)
32  {
33  LOG_NOTICE << "Trying to connect to " << m_endpoint;
34  connect();
35  if (!m_connected) {
36  LOG_ERROR << "Connection to " << m_endpoint << " failed";
37  }
38  }
39 
40  void sock_reset()
41  {
42  stop();
43  connect();
44  }
45 
46  bool sendIfPossible(const Frame& data)
47  {
48 
49  if (! m_connected)
50  {
51  sock_reset();
52 
53  if (! m_connected)
54  {
55  m_cbuffer.push_back(data);
56  return false;
57  }
58  }
59 
60  while (m_cbuffer.size())
61  {
62  if (send(m_cbuffer.front()))
63  {
64  m_cbuffer.pop_front();
65  }
66  else
67  {
68  break;
69  }
70  }
71  if (! send(data))
72  {
73  m_cbuffer.push_back(data);
74  }
75 
76  return m_connected;
77  }
78 
80  {
81  stop();
82  }
83 
84  friend class RecipientsHandler;
85 
86  private:
87 
88  void connect()
89  {
90  boost::system::error_code ec;
91  m_sock.connect(m_endpoint, ec);
92  m_connected = !ec;
93 
94  if (m_connected) {
95 #if __APPLE__
96  boost::asio::socket_base::send_buffer_size option(6108864);
97 #else
98  boost::asio::socket_base::send_buffer_size option(67108864);
99 #endif
100  m_sock.set_option(option);
101  LOG_NOTICE << "Connection to " << m_endpoint << " succeeded";
102  boost::system::error_code ec;
103  m_sock.shutdown(boost::asio::ip::tcp::socket::shutdown_receive, ec);
104  }
105  }
106 
107  void stop()
108  {
109  boost::system::error_code ec;
110  m_sock.shutdown(boost::asio::ip::tcp::socket::shutdown_send, ec);
111  m_sock.close(ec);
112  }
113 /**
114  * Send data
115  *
116  * \param data the Frame to send.
117  * \return true if OK; else false
118  */
119  bool send(const Frame& data)
120  {
121  boost::system::error_code ec;
122  boost::asio::write(m_sock, boost::asio::buffer(data.data(), data.getFrameLength()), ec);
123  m_connected = !ec;
124 
125  if (ec) {
126  LOG_ERROR << "Error transmitting data to " << m_endpoint << ": " << ec;
127  }
128  return m_connected;
129  }
130 };
131 
132 #endif // RECIPIENT_HH
Template Frame for ARS data.
Definition: frame.hh:13
bool send(const Frame &data)
Send data.
Definition: recipient.hh:119
boost::asio::ip::tcp::endpoint m_endpoint
Definition: recipient.hh:18
void connect()
Definition: recipient.hh:88
CircularBuffer m_cbuffer
Definition: recipient.hh:19
boost::asio::ip::tcp::socket m_sock
Definition: recipient.hh:17
void sock_reset()
Definition: recipient.hh:40
Recipient(boost::asio::io_service &service, const boost::asio::ip::tcp::endpoint &endpoint, size_t circbuff_size)
Definition: recipient.hh:24
bool sendIfPossible(const Frame &data)
Definition: recipient.hh:46
~Recipient()
Definition: recipient.hh:79
void stop()
Definition: recipient.hh:107
bool m_connected
Definition: recipient.hh:20
bool write(const Vec &v, std::ostream &os)
Write a Vec(tor) to a stream.
Definition: io_ascii.hh:155
#define LOG_ERROR
Definition: log.hh:111
#define LOG_NOTICE
Definition: log.hh:112
boost::circular_buffer< Frame > CircularBuffer
Definition: recipient.hh:13