libjmmcg  release_579_6_g8cffd
A C++ library containing an eclectic mix of useful, advanced components.
connection.hpp
Go to the documentation of this file.
1 #ifndef ISIMUD_EXCHANGES_COMMON_CONNECTION_HPP
2 #define ISIMUD_EXCHANGES_COMMON_CONNECTION_HPP
3 
4 /******************************************************************************
5 ** Copyright © 2015 by J.M.McGuiness, isimud@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 
22 #include "socket_type.hpp"
23 
24 #include "core/msg_processor.hpp"
25 
26 #include <boost/mpl/end.hpp>
27 #include <boost/mpl/find.hpp>
28 
29 namespace isimud { namespace ISIMUD_VER_NAMESPACE { namespace exchanges { namespace common {
30 
31 /// A class that wraps a link to an exchange.
32 template<class MsgDetails, class ConnPol>
33 class connection {
34 public:
35  /// A type containing the details of the messages that will be sent to and received from the exchange.
36  using msg_details_t=MsgDetails;
37  /// The connection policy that should be used to connect to the specified exchange.
38  using conn_pol_t=ConnPol;
39  using ctor_args=conn_pol_t;
40  using skt_mgr_t=socket_type::skt_mgr_t;
43 
44  const conn_pol_t conn_pol_;
45 
46  /// Connect to the exchange using the connection policy specified.
47  /**
48  \param conn_pol The specified connection policy, that includes details of the exchange to which the link should be made.
49  */
50  connection(conn_pol_t const &conn_pol, skt_mgr_t::socket_priority priority, std::size_t incoming_cpu);
51 
52  /// Send a message to the specified, connected, exchange.
53  /**
54  \param msg The client-side message to send to the connected exchange.
55  */
56  template<
57  class Msg
58  >
59  typename std::enable_if<
60  !std::is_same<
61  typename boost::mpl::find<typename msg_details_t::client_to_exchange_messages_t, Msg>::type,
62  typename boost::mpl::end<typename msg_details_t::client_to_exchange_messages_t>::type
63  >::value,
64  void
65  >::type send(Msg const &msg);
66 
67  /// Receive a message from the specified, connected, exchange.
68  /**
69  \param msg The particular type of client-side message to receive from the connected exchange. We must know the message that should be received, as specified by the protocol.
70  */
71  template<
72  class Msg
73  >
74  typename std::enable_if<
75  !std::is_same<
76  typename boost::mpl::find<typename msg_details_t::exchange_to_client_messages_t, Msg>::type,
77  typename boost::mpl::end<typename msg_details_t::exchange_to_client_messages_t>::type
78  >::value,
79  void
80  >::type receive(Msg &msg);
81 
82  void stop();
83 
84  skt_mgr_t::socket_t &socket() noexcept(true) {
85  return link.socket();
86  }
87 
88  std::string to_string() const noexcept(false);
89 
90 private:
91  skt_mgr_t link;
92 };
93 
94 template<class MsgDetails, class ConnPol> inline std::ostream &
95 operator<<(std::ostream &os, connection<MsgDetails, ConnPol> const &ec) noexcept(false);
96 
97 /// A class that wraps a link from an exchange to a client.
98 template<class ExchgToClientProcessingRules, class ConnPol>
99 class connection_processor final {
100 public:
101  using msg_processor_t=libjmmcg::socket::msg_processor<ExchgToClientProcessingRules>;
102  using proc_rules_t=typename msg_processor_t::proc_rules_t;
103  using msg_details_t=typename proc_rules_t::src_msg_details_t;
104  using connection_t=connection<msg_details_t, ConnPol>;
105  using conn_pol_t=typename connection_t::conn_pol_t;
106  using socket_t=typename connection_t::socket_t;
107  using socket_priority=typename connection_t::socket_priority;
108  using ctor_args=typename connection_t::ctor_args;
109 
110  connection_processor(ctor_args const &details, socket_priority priority, std::size_t incoming_cpu, proc_rules_t const &proc_rules) noexcept(false);
111  ~connection_processor() noexcept(false);
112 
113  template<class ClientCxn, class LatencyTimestamps>
114  bool read_and_process_a_msg(ClientCxn &dest_link, LatencyTimestamps &ts) noexcept(false);
115 
116  socket_t &socket() noexcept(true) {
117  assert(cxn_.socket().is_open());
118  return cxn_.socket();
119  }
120 
121  void stop();
122 
123  bool is_logged_on() const noexcept(true) {
124  return static_cast<bool>(logged_on_);
125  }
126 
127  std::string to_string() const noexcept(false);
128 
129 private:
130  std::atomic<bool> logged_on_{false};
131  msg_processor_t processor;
132  /**
133  * This wraps the socket connected to the exchange.
134  */
135  connection_t cxn_;
136 };
137 
138 template<class ExchgToClientProcessingRules, class ConnPol> inline std::ostream &
139 operator<<(std::ostream &os, connection_processor<ExchgToClientProcessingRules, ConnPol> const &ec) noexcept(false);
140 
141 } } } }
142 
143 #include "connection_impl.hpp"
144 
145 #endif