text: //
  // Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
  //
  // Distributed under the Boost Software License, Version 1.0. (See accompanying
  // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  //
  // Official repository: https://github.com/boostorg/beast
  //
  
  //------------------------------------------------------------------------------
  //
  // Example: WebSocket SSL client, synchronous
  //
  //------------------------------------------------------------------------------
  
  #include "example/common/root_certificates.hpp"
  
  #include <boost/beast/core.hpp>
  #include <boost/beast/websocket.hpp>
  #include <boost/beast/websocket/ssl.hpp>
  #include <boost/asio/connect.hpp>
  #include <boost/asio/ip/tcp.hpp>
  #include <boost/asio/ssl/stream.hpp>
  #include <cstdlib>
  #include <iostream>
  #include <string>
  
  using tcp = boost::asio::ip::tcp;               // from <boost/asio/ip/tcp.hpp>
  namespace ssl = boost::asio::ssl;               // from <boost/asio/ssl.hpp>
  namespace websocket = boost::beast::websocket;  // from <boost/beast/websocket.hpp>
  
  // Sends a WebSocket message and prints the response
  int main(int argc, char** argv)
  {
      try
      {
          // Check command line arguments.
          if(argc != 4)
          {
              std::cerr <<
                  "Usage: websocket-client-sync-ssl <host> <port> <text>\n" <<
                  "Example:\n" <<
                  "    websocket-client-sync-ssl echo.websocket.org 443 \"Hello, world!\"\n";
              return EXIT_FAILURE;
          }
          auto const host = argv[1];
          auto const port = argv[2];
          auto const text = argv[3];
  
          // The io_context is required for all I/O
          boost::asio::io_context ioc;
  
          // The SSL context is required, and holds certificates
          ssl::context ctx{ssl::context::sslv23_client};
  
          // This holds the root certificate used for verification
          load_root_certificates(ctx);
  
          // These objects perform our I/O
          tcp::resolver resolver{ioc};
          websocket::stream<ssl::stream<tcp::socket>> ws{ioc, ctx};
  
          // Look up the domain name
          auto const results = resolver.resolve(host, port);
  
          // Make the connection on the IP address we get from a lookup
          boost::asio::connect(ws.next_layer().next_layer(), results.begin(), results.end());
  
          // Perform the SSL handshake
          ws.next_layer().handshake(ssl::stream_base::client);
  
          // Perform the websocket handshake
          ws.handshake(host, "/");
  
          // Send the message
          ws.write(boost::asio::buffer(std::string(text)));
  
          // This buffer will hold the incoming message
          boost::beast::multi_buffer b;
  
          // Read a message into our buffer
          ws.read(b);
  
          // Close the WebSocket connection
          ws.close(websocket::close_code::normal);
  
          // If we get here then the connection is closed gracefully
  
          // The buffers() function helps print a ConstBufferSequence
          std::cout << boost::beast::buffers(b.data()) << std::endl;
      }
      catch(std::exception const& e)
      {
          std::cerr << "Error: " << e.what() << std::endl;
          return EXIT_FAILURE;
      }
      return EXIT_SUCCESS;
  }
  