main.cpp 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  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. //------------------------------------------------------------------------------
  10. /*
  11. WebSocket chat server, multi-threaded
  12. This implements a multi-user chat room using WebSocket. The
  13. `io_context` runs on any number of threads, specified at
  14. the command line.
  15. */
  16. //------------------------------------------------------------------------------
  17. #include "listener.hpp"
  18. #include "shared_state.hpp"
  19. #include <boost/asio/signal_set.hpp>
  20. #include <boost/smart_ptr.hpp>
  21. #include <iostream>
  22. #include <vector>
  23. int
  24. main(int argc, char* argv[])
  25. {
  26. // Check command line arguments.
  27. if (argc != 5)
  28. {
  29. std::cerr <<
  30. "Usage: websocket-chat-multi <address> <port> <doc_root> <threads>\n" <<
  31. "Example:\n" <<
  32. " websocket-chat-server 0.0.0.0 8080 . 5\n";
  33. return EXIT_FAILURE;
  34. }
  35. auto address = net::ip::make_address(argv[1]);
  36. auto port = static_cast<unsigned short>(std::atoi(argv[2]));
  37. auto doc_root = argv[3];
  38. auto const threads = std::max<int>(1, std::atoi(argv[4]));
  39. // The io_context is required for all I/O
  40. net::io_context ioc;
  41. // Create and launch a listening port
  42. boost::make_shared<listener>(
  43. ioc,
  44. tcp::endpoint{address, port},
  45. boost::make_shared<shared_state>(doc_root))->run();
  46. // Capture SIGINT and SIGTERM to perform a clean shutdown
  47. net::signal_set signals(ioc, SIGINT, SIGTERM);
  48. signals.async_wait(
  49. [&ioc](boost::system::error_code const&, int)
  50. {
  51. // Stop the io_context. This will cause run()
  52. // to return immediately, eventually destroying the
  53. // io_context and any remaining handlers in it.
  54. ioc.stop();
  55. });
  56. // Run the I/O service on the requested number of threads
  57. std::vector<std::thread> v;
  58. v.reserve(threads - 1);
  59. for(auto i = threads - 1; i > 0; --i)
  60. v.emplace_back(
  61. [&ioc]
  62. {
  63. ioc.run();
  64. });
  65. ioc.run();
  66. // (If we get here, it means we got a SIGINT or SIGTERM)
  67. // Block until all the threads exit
  68. for(auto& t : v)
  69. t.join();
  70. return EXIT_SUCCESS;
  71. }