listener.cpp 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. //
  2. // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
  3. //
  4. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. //
  7. // Official repository: https://github.com/vinniefalco/CppCon2018
  8. //
  9. #include "listener.hpp"
  10. #include "http_session.hpp"
  11. #include <iostream>
  12. listener::
  13. listener(
  14. net::io_context& ioc,
  15. tcp::endpoint endpoint,
  16. boost::shared_ptr<shared_state> const& state)
  17. : ioc_(ioc)
  18. , acceptor_(ioc)
  19. , state_(state)
  20. {
  21. beast::error_code ec;
  22. // Open the acceptor
  23. acceptor_.open(endpoint.protocol(), ec);
  24. if(ec)
  25. {
  26. fail(ec, "open");
  27. return;
  28. }
  29. // Allow address reuse
  30. acceptor_.set_option(net::socket_base::reuse_address(true), ec);
  31. if(ec)
  32. {
  33. fail(ec, "set_option");
  34. return;
  35. }
  36. // Bind to the server address
  37. acceptor_.bind(endpoint, ec);
  38. if(ec)
  39. {
  40. fail(ec, "bind");
  41. return;
  42. }
  43. // Start listening for connections
  44. acceptor_.listen(
  45. net::socket_base::max_listen_connections, ec);
  46. if(ec)
  47. {
  48. fail(ec, "listen");
  49. return;
  50. }
  51. }
  52. void
  53. listener::
  54. run()
  55. {
  56. // The new connection gets its own strand
  57. acceptor_.async_accept(
  58. net::make_strand(ioc_),
  59. beast::bind_front_handler(
  60. &listener::on_accept,
  61. shared_from_this()));
  62. }
  63. // Report a failure
  64. void
  65. listener::
  66. fail(beast::error_code ec, char const* what)
  67. {
  68. // Don't report on canceled operations
  69. if(ec == net::error::operation_aborted)
  70. return;
  71. std::cerr << what << ": " << ec.message() << "\n";
  72. }
  73. // Handle a connection
  74. void
  75. listener::
  76. on_accept(beast::error_code ec, tcp::socket socket)
  77. {
  78. if(ec)
  79. return fail(ec, "accept");
  80. else
  81. // Launch a new session for this connection
  82. boost::make_shared<http_session>(
  83. std::move(socket),
  84. state_)->run();
  85. // The new connection gets its own strand
  86. acceptor_.async_accept(
  87. net::make_strand(ioc_),
  88. beast::bind_front_handler(
  89. &listener::on_accept,
  90. shared_from_this()));
  91. }