28template <
typename REQ,
typename RESP>
class server :
public i_server<REQ, RESP> {
29 typedef typename std::shared_ptr<connection<RESP, REQ>> con_ptr;
32 struct forward_session :
public con_listener {
34 : server_instance(server_)
37 virtual ~forward_session() {}
39 con_ptr& get_connection() {
return conn_shptr; }
42 std::shared_ptr<con_listener> ptr = std::enable_shared_from_this<con_listener>::shared_from_this();
43 conn_shptr->add_listener(ptr);
44 typename connection<RESP, REQ>::endpoint_t endpoint = conn_shptr->socket().remote_endpoint();
45 CPPLOG(TRACE,
"tcp4tlm::server") <<
"forward_session::start(), got connected";
46 server_instance->server_send_completed(conn_shptr,
true);
47 return server_instance->is_shutdown_requested();
50 void receive_completed(
const boost::system::error_code& e,
const REQ*
const data) {
52 CPPLOG(WARN,
"tcp4tlm::server") <<
"Client closed connection (" << e.message() <<
")";
55 CPPLOG(ERR,
"tcp4tlm::server") <<
"Communication error (" << e.message() <<
")";
58 server_instance->server_receive_completed(conn_shptr, data);
61 void send_completed(
const boost::system::error_code& e) {
63 server_instance->server_send_completed(conn_shptr);
65 CPPLOG(ERR,
"tcp4tlm::server") << e.message() <<
"(" << e <<
")";
74 friend struct forward_session;
77 server(std::size_t thread_pool_size = 4)
78 : thread_pool_size(thread_pool_size)
82 , server_running(
false)
83 , shutdown_requested(
false) {}
87#ifdef BOOST_ASIO_HAS_LOCAL_SOCKETS
88 long set_acceptor_endpoint(std::shared_ptr<boost::asio::local::stream_protocol::acceptor>& a,
unsigned short port);
90 long set_acceptor_endpoint(std::shared_ptr<boost::asio::ip::tcp::acceptor>& a,
unsigned short port);
92 void start_server(
unsigned short port,
char* name = NULL);
94 void request_shutdown() {
95 if(!shutdown_requested) {
96 shutdown_requested =
true;
101 bool is_shutdown_requested() {
return shutdown_requested; }
103 void shutdown_server();
105 virtual boost::asio::io_context& get_io_service() {
return io_service; }
107 bool is_server_running() {
return server_running; }
109 void create_new_session() {
110 std::shared_ptr<forward_session> forward_session_ptr(
new forward_session(
this));
111 acceptor->async_accept(
112 forward_session_ptr->get_connection()->socket(),
113 [
this, forward_session_ptr](
const boost::system::error_code& error) { handle_accept(error, forward_session_ptr); });
117 const typename connection<RESP, REQ>::acceptor_t& get_acceptor() {
return *acceptor; };
120 void handle_accept(
const boost::system::error_code& e, std::shared_ptr<forward_session> session) {
122 if(!session->start())
123 create_new_session();
125 CPPLOG(ERR,
"tcp4tlm::server") << e.message();
129 std::size_t thread_pool_size;
130 boost::asio::io_context io_service;
131 std::shared_ptr<boost::asio::executor_work_guard<boost::asio::io_context::executor_type>> io_service_work;
132 std::shared_ptr<typename connection<RESP, REQ>::acceptor_t> acceptor;
133 boost::thread_group threads;
135 bool shutdown_requested;
140long server<REQ, RESP>::set_acceptor_endpoint(std::shared_ptr<boost::asio::local::stream_protocol::acceptor>& a,
unsigned short port) {