// Called when the timer expires. // We operate the timer continuously this simplifies the code. // void on_timer(error_code ec) { if(ec && ec != boost::asio::error::operation_aborted) return fail("timer", ec); // Verify that the timer really expired // since the deadline may have moved. // if(timer_.expires_at() <= clock_type::now()) { // Closing the socket cancels all outstanding // operations. They will complete with // boost::asio::error::operation_aborted // ws_.next_layer().close(ec); return; } // Wait on the timer timer_.async_wait( strand_.wrap(std::bind( &connection::on_timer, shared_from_this(), std::placeholders::_1))); }
void accept() { // Clean up any previous connection. boost::beast::error_code ec; socket_.close(ec); buffer_.consume(buffer_.size()); acceptor_.async_accept( socket_, [this](boost::beast::error_code ec) { if (ec) { accept(); } else { // Request must be fully processed within 60 seconds. request_deadline_.expires_after( std::chrono::seconds(60)); read_request(); } }); }
void onTimer (boost::system::error_code ec) { if (ec) { if (ec != boost::asio::error::operation_aborted) journal_.error << "onTimer: " << ec.message(); return; } logic_.onTimer(); timer_.expires_from_now(std::chrono::seconds(1), ec); timer_.async_wait(strand_.wrap(exec_.wrap( std::bind(&ManagerImp::onTimer, this, beast::asio::placeholders::error)))); }
void onStop() { boost::system::error_code ec; timer_.cancel(ec); logic_.stop(); exec_.async_wait([this]() { stopped(); }); }
void check_deadline() { // The deadline may have moved, so check it has really passed. if (request_deadline_.expiry() <= std::chrono::steady_clock::now()) { // Close socket to cancel any outstanding operation. boost::beast::error_code ec; socket_.close(); // Sleep indefinitely until we're given a new deadline. request_deadline_.expires_at( std::chrono::steady_clock::time_point::max()); } request_deadline_.async_wait( [this](boost::beast::error_code) { check_deadline(); }); }
// Read a message from the websocket stream void do_read() { // Put the read on the timer timer_.expires_from_now(std::chrono::seconds(15)); // Read a message ws_.async_read(buffer_, strand_.wrap(std::bind( &connection::on_read, shared_from_this(), std::placeholders::_1))); }
// Called immediately after the connection is created. // We keep this separate from the constructor because // shared_from_this may not be called from constructors. void run() { // Run the timer on_timer({}); // Put the handshake on the timer timer_.expires_from_now(std::chrono::seconds(15)); // Read the websocket handshake and send the response ws_.async_accept_ex( [](websocket::response_type& res) { res.insert(http::field::server, "websocket-server-async"); }, strand_.wrap(std::bind( &connection::on_accept, shared_from_this(), std::placeholders::_1))); }
// Called after the message read completes void on_read(error_code ec) { // This error means the other side // closed the websocket stream. if(ec == websocket::error::closed) return; if(ec) return fail("read", ec); // Put the write on the timer timer_.expires_from_now(std::chrono::seconds(15)); // Write the received message back ws_.binary(ws_.got_binary()); ws_.async_write(buffer_.data(), strand_.wrap(std::bind( &connection::on_write, shared_from_this(), std::placeholders::_1))); }