// // async_tcp_client.cpp // ~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff 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) // #include #include #include #include #include #include #include #include #include "mrvServer.h" using boost::asio::deadline_timer; using boost::asio::ip::tcp; // // This class manages socket timeouts by applying the concept of a deadline. // Some asynchronous operations are given deadlines by which they must complete. // Deadlines are enforced by an "actor" that persists for the lifetime of the // client object: // // +----------------+ // | | // | check_deadline |<---+ // | | | // +----------------+ | async_wait() // | | // +---------+ // // If the deadline actor determines that the deadline has expired, the socket // is closed and any outstanding operations are consequently cancelled. // // Connection establishment involves trying each endpoint in turn until a // connection is successful, or the available endpoints are exhausted. If the // deadline actor closes the socket, the connect actor is woken up and moves to // the next endpoint. // // +---------------+ // | | // | start_connect |<---+ // | | | // +---------------+ | // | | // async_- | +----------------+ // connect() | | | // +--->| handle_connect | // | | // +----------------+ // : // Once a connection is : // made, the connect : // actor forks in two - : // : // an actor for reading : and an actor for // inbound messages: : sending heartbeats: // : // +------------+ : +-------------+ // | |<- - - - -+- - - - ->| | // | start_read | | start_write |<---+ // | |<---+ | | | // +------------+ | +-------------+ | async_wait() // | | | | // async_- | +-------------+ async_- | +--------------+ // read_- | | | write() | | | // until() +--->| handle_read | +--->| handle_write | // | | | | // +-------------+ +--------------+ // // The input actor reads messages from the socket, where messages are delimited // by the newline character. The deadline for a complete message is 30 seconds. // // The heartbeat actor sends a heartbeat (a message that consists of a single // newline character) every 10 seconds. In this example, no deadline is applied // message sending. // namespace mrv { class ViewerUI; class client : public ParseCommands { public: client(boost::asio::io_service& io_service, mrv::ViewerUI* v, bool client = false ); // Called by the user of the client class to initiate the connection // process. // The endpoint iterator will have been obtained using a tcp::resolver. void start(tcp::resolver::iterator endpoint_iter); // This function terminates all the actors to shut down the connection. It // may be called by the user of the client class, or by the class itself in // response to graceful termination or an unrecoverable error. void stop(); virtual void send( const std::string s ); private: void start_connect(tcp::resolver::iterator endpoint_iter); void handle_connect(const boost::system::error_code& ec, tcp::resolver::iterator endpoint_iter); void start_read(); void handle_read(const boost::system::error_code& ec); void start_write( const std::string& s ); void handle_write(const boost::system::error_code& ec); void check_deadline(); private: bool stopped_; bool client_; tcp::socket socket_; boost::asio::streambuf input_buffer_; deadline_timer deadline_; }; } // namespace mrv