libjmmcg  release_579_6_g8cffd
A C++ library containing an eclectic mix of useful, advanced components.
socket_server_manager_glibc.hpp
Go to the documentation of this file.
1 #ifndef LIBJMMCG_COER_SERVER_MANAGER_GLIBC_HPP
2 #define LIBJMMCG_COER_SERVER_MANAGER_GLIBC_HPP
3 
4 /******************************************************************************
5 ** Copyright © 2015 by J.M.McGuiness, coder@hussar.me.uk
6 **
7 ** This library is free software; you can redistribute it and/or
8 ** modify it under the terms of the GNU Lesser General Public
9 ** License as published by the Free Software Foundation; either
10 ** version 2.1 of the License, or (at your option) any later version.
11 **
12 ** This library is distributed in the hope that it will be useful,
13 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 ** Lesser General Public License for more details.
16 **
17 ** You should have received a copy of the GNU Lesser General Public
18 ** License along with this library; if not, write to the Free Software
19 ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21 
23 
24 #include <functional>
25 #include <memory>
26 
27 #ifdef __GCC__
28 # pragma GCC diagnostic push
29 # pragma GCC diagnostic ignored "-Wsuggest-final-methods"
30 # pragma GCC diagnostic ignored "-Wsuggest-final-types"
31 #endif
32 
33 namespace jmmcg { namespace LIBJMMCG_VER_NAMESPACE { namespace socket { namespace server_manager { namespace glibc {
34 
35 /// A simple TCP/IP socket wrapper using socket::server::wrapper for servers.
36 /**
37  \see socket::server::wrapper
38 */
39 template<class LkT>
40 class manager {
41 public:
42  using acceptor_t=socket::glibc::server::wrapper<LkT>;
43  using socket_t=socket::glibc::client::wrapper<LkT>;
44  using socket_priority=typename socket_t::socket_priority;
45 
46  /// A wrapper for a new client connection to the server.
47  class session : public std::enable_shared_from_this<session> {
48  public:
49  using ptr_type=std::shared_ptr<session>;
50 
51  explicit session(typename socket_t::socket_type accept_socket) noexcept(false)
52  : socket_(accept_socket) {
53  // Stuff to set once the socket is open...
54  }
55 
56  virtual ~session()=default;
57 
58  /// For loop-back connections, such as simulators.
59  template<class RecvProcMsgs>
60  bool process(RecvProcMsgs proc_fn) noexcept(false) {
61  return proc_fn(*this, socket_);
62  }
63 
64  /// For forwarding connections, such as the translator.
65  template<class RecvProcMsgs>
66  bool process(RecvProcMsgs proc_fn, socket_t &dest_socket) noexcept(false) {
67  return proc_fn(*this, dest_socket);
68  }
69 
70  virtual void start() {
71  }
72 
73  virtual void stop() {
74  socket_.close();
75  }
76 
77  socket_t &socket() noexcept(true) {
78  return socket_;
79  }
80 
81  std::string to_string() const noexcept(false);
82 
83  static ptr_type make(typename socket_t::socket_type accept_socket) noexcept(false) {
84  return std::make_shared<typename ptr_type::element_type>(accept_socket);
85  }
86 
87  protected:
88  socket_t socket_;
89  };
90  using server_to_client_flow_t=std::function<void (typename session::ptr_type)>;
91 
92  /// Create a new connection to the specified TCP socket using the TCP/IP protocol.
93  /**
94  \param addr The IPv4 or IPv6 address to which the connection should be made.
95  \param port_num The port number to which the connection should be made.
96  */
97  manager(boost::asio::ip::address const &addr, unsigned short port_num, std::size_t min_message_size, std::size_t max_message_size, unsigned short timeout, socket_priority priority, std::size_t incoming_cpu, server_to_client_flow_t &&server_to_client_flow);
98 
99  /// Blocking wait for a new connection from a client.
100  void run();
101 
102  void stop();
103 
104  static void set_options(acceptor_t &acceptor, socket_t &skt);
105 
106  std::string to_string() const noexcept(false);
107 
108 protected:
109  acceptor_t acceptor;
110  server_to_client_flow_t server_to_client_flow_;
111 
112  ~manager()=default;
113 
114  void set_options(socket_t &skt);
115 };
116 
117 template<class LkT>
118 inline std::ostream &
119 operator<<(std::ostream &os, typename manager<LkT>::tcp_connection const &ec) noexcept(false);
120 
121 template<class LkT>
122 inline std::ostream &
123 operator<<(std::ostream &os, manager<LkT> const &ec) noexcept(false);
124 
125 /// A simple TCP/IP socket wrapper using boost::asio for loop-back servers.
126 template<class SvrHBs, class LkT>
127 class loopback : public manager<LkT> {
128 public:
129  using base_t=manager<LkT>;
130  /// Start sending heartbeats upon a connection.
131  using heartbeats_t=SvrHBs;
132  using socket_t=typename base_t::socket_t;
133  using socket_priority=typename base_t::socket_priority;
134  using server_to_client_flow_t=typename base_t::server_to_client_flow_t;
135  using base_t::base_t;
136 
137  /**
138  \param dest The socket to which the received messages should be forwarded after suitable processing.
139  */
140  loopback(boost::asio::ip::address const &addr, unsigned short port_num, std::size_t min_message_size, std::size_t max_message_size, unsigned short timeout, socket_priority priority, std::size_t incoming_cpu, server_to_client_flow_t &&server_to_client_flow);
141 
142  /// Non-blocking call to wait for new connections from a client.
143  /**
144  \param proc_fn The operations to perform upon receiving a connection request from a client.
145  */
146  template<class RecvProcMsgs>
147  void start_accept(RecvProcMsgs proc_fn) noexcept(false);
148 
149 private:
150  class send_heartbeats;
151 };
152 
153 /// A simple TCP/IP socket wrapper using a socket wrapper for forwarding servers.
154 template<class LkT>
155 class forwarding : public manager<LkT> {
156 public:
157  using base_t=manager<LkT>;
158  using socket_t=typename base_t::socket_t;
159  using socket_priority=typename base_t::socket_priority;
160  using server_to_client_flow_t=typename base_t::server_to_client_flow_t;
161 
162  /**
163  \param dest The socket to which the received messages should be forwarded after suitable processing.
164  */
165  forwarding(boost::asio::ip::address const &addr, unsigned short port_num, std::size_t min_message_size, std::size_t max_message_size, unsigned short timeout, socket_priority priority, std::size_t incoming_cpu, server_to_client_flow_t &&server_to_client_flow, socket_t &dest);
166 
167  /// Non-blocking call to wait for new connections from a client.
168  /**
169  \param proc_fn The operations to perform upon receiving a connection request from a client.
170  */
171  template<class RecvProcMsgs>
172  void start_accept(RecvProcMsgs proc_fn) noexcept(false);
173 
174 private:
175  socket_t &dest_socket_;
176 };
177 
178 } } } } }
179 
181 
182 #ifdef __GCC__
183 # pragma GCC diagnostic pop
184 #endif
185 
186 #endif