CppWAMP
C++11 client library for the WAMP protocol
tcpacceptor.hpp
1 /*------------------------------------------------------------------------------
2  Copyright Butterfly Energy Systems 2014-2015, 2022.
3  Distributed under the Boost Software License, Version 1.0.
4  http://www.boost.org/LICENSE_1_0.txt
5 ------------------------------------------------------------------------------*/
6 
7 #ifndef CPPWAMP_INTERNAL_TCPACCEPTOR_HPP
8 #define CPPWAMP_INTERNAL_TCPACCEPTOR_HPP
9 
10 #include <cassert>
11 #include <memory>
12 #include <boost/asio/connect.hpp>
13 #include <boost/asio/ip/tcp.hpp>
14 #include <boost/asio/strand.hpp>
15 #include "../asiodefs.hpp"
16 
17 namespace wamp
18 {
19 
20 namespace internal
21 {
22 
23 //------------------------------------------------------------------------------
24 class TcpAcceptor
25 {
26 public:
27  using Socket = boost::asio::ip::tcp::socket;
28  using SocketPtr = std::unique_ptr<Socket>;
29 
30  template <typename TExecutorOrStrand>
31  TcpAcceptor(TExecutorOrStrand&& exec, const std::string addr,
32  unsigned short port)
33  : strand_(std::forward<TExecutorOrStrand>(exec)),
34  endpoint_(boost::asio::ip::address::from_string(addr), port)
35  {}
36 
37  template <typename TExecutorOrStrand>
38  TcpAcceptor(TExecutorOrStrand&& exec, unsigned short port)
39  : strand_(std::forward<TExecutorOrStrand>(exec)),
40  endpoint_(boost::asio::ip::tcp::v4(), port)
41  {}
42 
43  IoStrand strand() {return strand_;}
44 
45  template <typename F>
46  void establish(F&& callback)
47  {
48  struct Accepted
49  {
50  TcpAcceptor* self;
51  typename std::decay<F>::type callback;
52 
53  void operator()(AsioErrorCode ec)
54  {
55  if (ec)
56  {
57  self->acceptor_.reset();
58  self->socket_.reset();
59  }
60  callback(ec, std::move(self->socket_));
61  }
62  };
63 
64  assert(!socket_ && "Accept already in progress");
65 
66  if (!acceptor_)
67  acceptor_.reset(new tcp::acceptor(strand_, endpoint_));
68  socket_.reset(new Socket(strand_));
69 
70  // AsioListener will keep this object alive until completion.
71  acceptor_->async_accept(*socket_,
72  Accepted{this, std::forward<F>(callback)});
73  }
74 
75  void cancel()
76  {
77  if (acceptor_)
78  acceptor_->close();
79  }
80 
81 private:
82  using tcp = boost::asio::ip::tcp;
83 
84  IoStrand strand_;
85  tcp::endpoint endpoint_;
86  std::unique_ptr<tcp::acceptor> acceptor_;
87  SocketPtr socket_;
88 };
89 
90 } // namespace internal
91 
92 } // namespace wamp
93 
94 
95 #endif // CPPWAMP_INTERNAL_TCPACCEPTOR_HPP
wamp::IoStrand
boost::asio::strand< AnyIoExecutor > IoStrand
Serializes I/O operations.
Definition: asiodefs.hpp:41
wamp
Definition: anyhandler.hpp:36
wamp::AsioErrorCode
boost::system::error_code AsioErrorCode
Type used by Boost.Asio for reporting errors.
Definition: asiodefs.hpp:44