void
    on_read(
        boost::system::error_code ec,
        std::size_t bytes_transferred)
    {
        boost::ignore_unused(bytes_transferred);

        // This indicates that the session was closed
        if(ec == websocket::error::closed)
            return;

        if(ec)
            fail(ec, "read");

        // Echo the message
        ws_.text(ws_.got_text());
        ws_.async_write(
            buffer_.data(),
            boost::asio::bind_executor(
                strand_,
                std::bind(
                    &session::on_write,
                    shared_from_this(),
                    std::placeholders::_1,
                    std::placeholders::_2)));
    }
 // Start the asynchronous operation
 void
 run()
 {
     // Accept the websocket handshake
     ws_.async_accept(
         boost::asio::bind_executor(
             strand_,
             std::bind(
                 &session::on_accept,
                 shared_from_this(),
                 std::placeholders::_1)));
 }
 // Start the asynchronous operation
 void
 run()
 {
     // Perform the SSL handshake
     ws_.next_layer().async_handshake(
         ssl::stream_base::server,
         boost::asio::bind_executor(
             strand_,
             std::bind(
                 &session::on_handshake,
                 shared_from_this(),
                 std::placeholders::_1)));
 }
 void
 do_read()
 {
     // Read a message into our buffer
     ws_.async_read(
         buffer_,
         boost::asio::bind_executor(
             strand_,
             std::bind(
                 &session::on_read,
                 shared_from_this(),
                 std::placeholders::_1,
                 std::placeholders::_2)));
 }
    void
    on_handshake(boost::system::error_code ec)
    {
        if(ec)
            return fail(ec, "handshake");

        // Accept the websocket handshake
        ws_.async_accept(
            boost::asio::bind_executor(
                strand_,
                std::bind(
                    &session::on_accept,
                    shared_from_this(),
                    std::placeholders::_1)));
    }
 // Take ownership of the socket
 session(tcp::socket socket, ssl::context& ctx)
     : socket_(std::move(socket))
     , ws_(socket_, ctx)
     , strand_(ws_.get_executor())
 {
 }
 // Take ownership of the socket
 explicit
 session(tcp::socket socket)
     : ws_(std::move(socket))
     , strand_(ws_.get_executor())
 {
 }