packio
server.h
Go to the documentation of this file.
1 // This Source Code Form is subject to the terms of the Mozilla Public
2 // License, v. 2.0. If a copy of the MPL was not distributed with this
3 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4 
5 #ifndef PACKIO_SERVER_H
6 #define PACKIO_SERVER_H
7 
10 
11 #include <memory>
12 
13 #include "dispatcher.h"
14 #include "internal/config.h"
15 #include "internal/log.h"
16 #include "internal/utils.h"
17 #include "server_session.h"
18 #include "traits.h"
19 
20 namespace packio {
21 
26 template <typename Rpc, typename Acceptor, typename Dispatcher = dispatcher<Rpc>>
27 class server
28  : public std::enable_shared_from_this<server<Rpc, Acceptor, Dispatcher>> {
29 public:
30  using rpc_type = Rpc;
31  using acceptor_type = Acceptor;
32  using protocol_type = typename Acceptor::protocol_type;
33  using dispatcher_type = Dispatcher;
34  using executor_type =
35  typename acceptor_type::executor_type;
36  using socket_type = std::decay_t<decltype(
37  std::declval<acceptor_type>().accept())>;
39 
40  using std::enable_shared_from_this<server<Rpc, Acceptor, Dispatcher>>::shared_from_this;
41 
46  server(acceptor_type acceptor, std::shared_ptr<dispatcher_type> dispatcher)
47  : acceptor_{std::move(acceptor)}, dispatcher_ptr_{std::move(dispatcher)}
48  {
49  }
50 
53  : server{std::move(acceptor), std::make_shared<dispatcher_type>()}
54  {
55  }
56 
58  acceptor_type& acceptor() { return acceptor_; }
60  const acceptor_type& acceptor() const { return acceptor_; }
61 
63  std::shared_ptr<dispatcher_type> dispatcher() { return dispatcher_ptr_; }
65  std::shared_ptr<const dispatcher_type> dispatcher() const
66  {
67  return dispatcher_ptr_;
68  }
69 
71  executor_type get_executor() { return acceptor().get_executor(); }
72 
78  template <PACKIO_COMPLETION_TOKEN_FOR(void(error_code, std::shared_ptr<session_type>))
79  ServeHandler PACKIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
81  ServeHandler&& handler PACKIO_DEFAULT_COMPLETION_TOKEN(executor_type))
82  {
83  return net::async_initiate<
84  ServeHandler,
85  void(error_code, std::shared_ptr<session_type>)>(
86  initiate_async_serve(this), handler);
87  }
88 
91  {
92  async_serve([self = shared_from_this()](auto ec, auto session) {
93  if (ec) {
94  return;
95  }
96 
97  session->start();
98  self->async_serve_forever();
99  });
100  }
101 
102 private:
103  class initiate_async_serve {
104  public:
105  using executor_type = typename server::executor_type;
106 
107  explicit initiate_async_serve(server* self) : self_(self) {}
108 
109  executor_type get_executor() const noexcept
110  {
111  return self_->get_executor();
112  }
113 
114  template <typename ServeHandler>
115  void operator()(ServeHandler&& handler)
116  {
117  PACKIO_STATIC_ASSERT_TTRAIT(ServeHandler, session_type);
118  PACKIO_TRACE("async_serve");
119 
120  self_->acceptor_.async_accept(
121  [self = self_->shared_from_this(),
122  handler = std::forward<ServeHandler>(handler)](
123  error_code ec, socket_type sock) mutable {
124  std::shared_ptr<session_type> session;
125  if (ec) {
126  PACKIO_WARN("accept error: {}", ec.message());
127  }
128  else {
129  internal::set_no_delay(sock);
130  session = std::make_shared<session_type>(
131  std::move(sock), self->dispatcher_ptr_);
132  }
133  handler(ec, std::move(session));
134  });
135  }
136 
137  private:
138  server* self_;
139  };
140 
141  acceptor_type acceptor_;
142  std::shared_ptr<dispatcher_type> dispatcher_ptr_;
143 };
144 
149 template <typename Rpc, typename Acceptor, typename Dispatcher = dispatcher<Rpc>>
150 auto make_server(Acceptor&& acceptor)
151 {
152  return std::make_shared<server<Rpc, Acceptor, Dispatcher>>(
153  std::forward<Acceptor>(acceptor));
154 }
155 
156 } // packio
157 
158 #endif // PACKIO_SERVER_H
The dispatcher class, used to store and dispatch procedures.
Definition: dispatcher.h:33
The server_session class, created by the server.
Definition: server_session.h:26
The server class.
Definition: server.h:28
server(acceptor_type acceptor)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: server.h:52
const acceptor_type & acceptor() const
Get the underlying acceptor, const.
Definition: server.h:60
Acceptor acceptor_type
The acceptor type.
Definition: server.h:31
typename acceptor_type::executor_type executor_type
The executor type.
Definition: server.h:35
std::shared_ptr< const dispatcher_type > dispatcher() const
Get the dispatcher, const.
Definition: server.h:65
auto async_serve(ServeHandler &&handler=typename net::default_completion_token< executor_type >::type())
Accept one connection and initialize a session for it.
Definition: server.h:80
server(acceptor_type acceptor, std::shared_ptr< dispatcher_type > dispatcher)
The constructor.
Definition: server.h:46
void async_serve_forever()
Accept connections and automatically start the associated sessions forever.
Definition: server.h:90
std::shared_ptr< dispatcher_type > dispatcher()
Get the dispatcher.
Definition: server.h:63
executor_type get_executor()
Get the executor associated with the object.
Definition: server.h:71
Rpc rpc_type
The RPC protocol type.
Definition: server.h:30
acceptor_type & acceptor()
Get the underlying acceptor.
Definition: server.h:58
std::decay_t< decltype(std::declval< acceptor_type >().accept())> socket_type
The connection socket type.
Definition: server.h:37
typename Acceptor::protocol_type protocol_type
The protocol type.
Definition: server.h:32
Dispatcher dispatcher_type
The dispatcher type.
Definition: server.h:33
Class dispatcher.
The packio namespace.
Definition: arg.h:14
auto make_server(Acceptor &&acceptor)
Create a server from an acceptor.
Definition: server.h:150
Class server_session.
Traits definition.