#include #include #include #include #include #include #include "chat_messages.hpp" namespace chat { using namespace chat; using namespace boost; using boost::asio::ip::tcp; class client_network_manager { private: asio::io_service& _ios; tcp::socket _socket; asio::streambuf _isb;//<-------. asio::streambuf _osb;//<---. | std::istream _is;//--------|---' std::ostream _os;//--------' std::string _login; static void throw_if_error(boost::system::error_code& ec) { if (ec) throw std::runtime_error("Networking error: " + ec.message()); } std::string receive_message_sync() { std::string data; asio::read_until(_socket, _isb, byte(message::TERM)); std::getline(_is, data, byte(message::TERM)); return data; } void handshake(boost::system::error_code ec, tcp::resolver::iterator) { throw_if_error(ec); std::cout << receive_message_sync() << '\n'; _os << chat_message(message::HELLO); _os << chat_message(message::NEPTUN, _login); std::reverse(_login.begin(), _login.end()); _os << chat_message(message::PASSW, _login); asio::write(_socket, _osb); std::cout << receive_message_sync() << '\n'; std::cout << receive_message_sync() << '\n'; std::cout << receive_message_sync() << '\n'; receive(); } void receive() { asio::async_read_until(_socket, _isb, byte(message::TERM), [this](boost::system::error_code ec, size_t) { throw_if_error(ec); std::string data; std::getline(_is, data, byte(message::TERM)); switch (data[0]) { // TODO: handle stuff case byte(message::LOGIN): std::cout << "login\n"; break; case byte(message::PING): std::cout << "ping\n"; break; } receive(); }); } void connect(tcp::resolver::iterator epit) { asio::async_connect ( _socket, epit, std::bind(&client_network_manager::handshake, this, std::placeholders::_1, std::placeholders::_2) ); } public: client_network_manager(asio::io_service& ioservice, tcp::resolver::iterator epit, std::string login) : _ios(ioservice), _socket(_ios), _isb(), _osb(), _is(&_isb), _os(&_osb), _login(login) { connect(epit); } void send(chat_message message) { _ios.post([this, message] { asio::async_write(_socket, asio::buffer(message.get()), [](boost::system::error_code, size_t) {}); }); } }; }