libjmmcg  release_579_6_g8cffd
A C++ library containing an eclectic mix of useful, advanced components.
socket_server.hpp
Go to the documentation of this file.
1 #ifndef LIBJMMCG_CORE_SOCKET_SERVER_HPP
2 #define LIBJMMCG_CORE_SOCKET_SERVER_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 
22 #include "application.hpp"
23 #include "exception.hpp"
24 #include "jthread.hpp"
26 #include "msg_processor.hpp"
28 
29 #include "config.h"
30 
31 #include <boost/exception/diagnostic_information.hpp>
32 #include <boost/exception_ptr.hpp>
33 #include <boost/program_options.hpp>
34 
35 #include <iostream>
36 #include <iterator>
37 
38 namespace jmmcg { namespace LIBJMMCG_VER_NAMESPACE { namespace socket {
39 
40 /// A very simple socket-based server.
41 /**
42  This server only handles a single client at any time. Re-connections are possible.
43  */
44 template<
45  class ProcessingRules, ///< The translation rules to use to convert messages received from the client to server-side messages & via-versa.
46  class SvrMgr ///< The particular type of server that should be run. e.g. does it forward messages, or send them back?
47 >
48 class svr final : public application {
49 public:
50  using base_t=application;
51  using exception_type=crt_exception<ppd::platform_api, ppd::heavyweight_threading>;
52  using svr_mgr_t=SvrMgr;
53  using server_to_client_flow_t=typename svr_mgr_t::server_to_client_flow_t;
54  using socket_t=typename svr_mgr_t::socket_t;
55  using socket_priority=typename svr_mgr_t::socket_priority;
56  using msg_processor_t=msg_processor<ProcessingRules>;
57  using proc_rules_t=typename msg_processor_t::proc_rules_t;
58  using thread_t=ppd::jthread;
59 
60  struct ctor_args {
61  using addr_t=boost::asio::ip::address;
62  using port_t=unsigned short;
63  using pr_t=proc_rules_t;
64 
65  addr_t addr;
66  port_t port;
67  pr_t proc_ops;
68  };
69 
70  /// A simple socket-based server that listens to connections to the specified endpoint and responds to messages received in the specified manner. i.e. loops them back.
71  /**
72  \param addr The IPv4 or IPv6 address to which the connection should be made.
73  \param port_num The port number to which the connection should be made.
74  \param priority The priority at which the TCP messages should be sent, relating to QoS.
75  \param proc_ops The responses that the server should make to messages received on the endpoint, sent back to the connected endpoint.
76 
77  \see ctor_args
78  */
79  template<class LatencyTimestamps, class =typename std::enable_if<std::is_class<typename LatencyTimestamps::period>::value>::type>
80  svr(boost::asio::ip::address const &addr, unsigned short port_num, unsigned short timeout, socket_priority priority, thread_t::thread_traits::api_params_type::processor_mask_type mask, const thread_t::thread_traits::api_params_type::priority_type cpu_priority, proc_rules_t const &proc_ops, LatencyTimestamps &ts, char const *svr_name, server_to_client_flow_t &&server_to_client_flow=[](auto const &) {}) noexcept(false);
81  template<class LatencyTimestamps, class =typename std::enable_if<std::is_class<typename LatencyTimestamps::period>::value>::type>
82  svr(boost::asio::ip::address const &addr, unsigned short port_num, socket_priority priority, thread_t::thread_traits::api_params_type::processor_mask_type mask, const thread_t::thread_traits::api_params_type::priority_type cpu_priority, proc_rules_t const &proc_ops, LatencyTimestamps &ts, char const *svr_name, server_to_client_flow_t &&server_to_client_flow=[](auto const &) {}) noexcept(false);
83  /// A simple socket-based server that listens to connections to the specified endpoint (e.g. a client that sends FIX messages) and responds to messages received in the specified manner. i.e. forwards the messages.
84  /**
85  \param addr The IPv4 or IPv6 address to which the connection should be made.
86  \param port_num The port number to which the connection should be made.
87  \param priority The priority at which the TCP messages should be sent, relating to QoS.
88  \param proc_ops The responses that the server should make to messages received on the endpoint.
89  \param dest_skt The socket to which the received messages should be forwarded after suitable processing. e.g. the exchange.
90 
91  \see ctor_args
92  */
93  template<class LatencyTimestamps, class =typename std::enable_if<std::is_class<typename LatencyTimestamps::period>::value>::type>
94  svr(boost::asio::ip::address const &addr, unsigned short port_num, unsigned short timeout, socket_priority priority, thread_t::thread_traits::api_params_type::processor_mask_type mask, const thread_t::thread_traits::api_params_type::priority_type cpu_priority, proc_rules_t const &proc_ops, socket_t &dest_skt, LatencyTimestamps &ts, char const *svr_name, server_to_client_flow_t &&server_to_client_flow=[](auto const &) {}) noexcept(false);
95  template<class LatencyTimestamps, class =typename std::enable_if<std::is_class<typename LatencyTimestamps::period>::value>::type>
96  svr(boost::asio::ip::address const &addr, unsigned short port_num, socket_priority priority, thread_t::thread_traits::api_params_type::processor_mask_type mask, const thread_t::thread_traits::api_params_type::priority_type cpu_priority, proc_rules_t const &proc_ops, socket_t &dest_skt, LatencyTimestamps &ts, server_to_client_flow_t &&server_to_client_flow=[](auto const &) {}) noexcept(false);
97  template<class LatencyTimestamps>
98  svr(ctor_args const &args, socket_priority priority, thread_t::thread_traits::api_params_type::processor_mask_type mask, const thread_t::thread_traits::api_params_type::priority_type cpu_priority, LatencyTimestamps &ts, server_to_client_flow_t &&server_to_client_flow=[](auto const &) {}) noexcept(false);
99  template<class LatencyTimestamps>
100  svr(ctor_args const &args, socket_t &dest_skt, unsigned short timeout, socket_priority priority, thread_t::thread_traits::api_params_type::processor_mask_type mask, const thread_t::thread_traits::api_params_type::priority_type cpu_priority, LatencyTimestamps &ts, char const *svr_name, server_to_client_flow_t &&server_to_client_flow=[](auto const &) {}) noexcept(false);
101  ~svr() noexcept(true);
102 
103  void stop() noexcept(true);
104 
105  /// A main() method for instantiating a stand-alone simulator.
106  /**
107  Use this within the CRT-main().
108  */
109  static int main(int argc, char const * const *argv) noexcept(true);
110 
111  std::string to_string() const noexcept(false);
112 
113 private:
114  boost::asio::ip::address const address;
115  const unsigned short port_number;
116  std::atomic<bool> exit_{false};
117  /**
118  \todo Need to check this for errors.
119  */
120  boost::exception_ptr client_ex{};
121  msg_processor_t processor;
122  svr_mgr_t manager;
123  thread_t io_thread;
124 
125  /// In a single thread, handle any connections from the client connected on the specified socket and forward those messages on.
126  /**
127  \param src_cxn The client socket, e.g. a FIX client.
128  \param dest_skt The destination socket, e.g. an exchange connection.
129  \return False to continue processing messages, true otherwise.
130  */
131  template<class LatencyTimestamps>
132  bool read_and_process_msgs(typename svr_mgr_t::session &src_cxn, socket_t &dest_skt, LatencyTimestamps &ts) noexcept(false);
133  template<class LatencyTimestamps>
134  bool read_and_process_msgs(typename svr_mgr_t::session &src_cxn, typename svr_mgr_t::session &dest_cxn, LatencyTimestamps &ts) noexcept(false);
135 
136  void run() noexcept(true);
137 };
138 
139 template<class ProcessingRules, class SvrMgr> inline std::ostream &
140 operator<<(std::ostream &os, svr<ProcessingRules, SvrMgr> const &ec) noexcept(false);
141 
142 } } }
143 
145 
146 #endif