class talk_to_svr : public boost::enable_shared_from_this<talk_to_svr>
, public coroutine, boost::noncopyable {
...
void step(const error_code & err = error_code(), size_t bytes = 0) {
reenter(this) { for (;;) {
yield async_write(sock_, write_buffer_, MEM_FN2(step,_1,_2) );
yield async_read_until( sock_, read_buffer_,"\n", MEM_
FN2(step,_1,_2));
yield service.post( MEM_FN(on_answer_from_server));
}} }
};
void step(const error_code & err = error_code(), size_t bytes = 0) {
reenter(this) {
yield async_write(sock_, write_buffer_, MEM_FN2(step,_1,_2) );
yield async_read_until( sock_, read_buffer_, "\n",MEM_
FN2(step,_1,_2));
yield service.post( MEM_FN(on_answer_from_server));
}
}
class talk_to_svr : public boost::enable_shared_from_this<talk_to_svr>
, public coroutine, boost::noncopyable {
talk_to_svr(const std::string & username) : ... {}
void start(ip::tcp::endpoint ep) {
sock_.async_connect(ep, MEM_FN2(step,_1,0) );
}
static ptr start(ip::tcp::endpoint ep, const std::string &
username) {
ptr new_(new talk_to_svr(username)); new_->start(ep); return
new_;
}
void step(const error_code & err = error_code(), size_t bytes = 0)
{
);
reenter(this) { for (;;) {
if ( !started_) {
started_ = true; std::ostream out(&write_buf_);
out << "login " << username_ << "\n";
}
yield async_write(sock_, write_buf_, MEM_FN2(step,_1,_2)
yield async_read_until( sock_,read_buf_,"\n", MEM_
FN2(step,_1,_2));
yield service.post( MEM_FN(on_answer_from_server));
}}
}
void on_answer_from_server() {
std::istream in(&read_buf_); std::string word; in >> word;
if ( word == "login") on_login();
else if ( word == "ping") on_ping();
else if ( word == "clients") on_clients();
read_buf_.consume( read_buf_.size());
if (write_buf_.size() > 0) service.post( MEM_FN2(step,error_
code(),0));
}
... private:
ip::tcp::socket sock_; streambuf read_buf_, write_buf_;
bool started_; std::string username_; deadline_timer timer_;
};
class talk_to_svr : ... {
...
void on_login() { do_ask_clients(); }
void on_ping() {
std::istream in(&read_buf_);
std::string answer; in >> answer;
if ( answer == "client_list_changed") do_ask_clients();
else postpone_ping();
}
void on_clients() {
std::ostringstream clients; clients << &read_buf_;
std::cout << username_ << ", new client list:" << clients.
str();
postpone_ping();
}
void do_ping() {
std::ostream out(&write_buf_); out << "ping\n";
service.post( MEM_FN2(step,error_code(),0));
}
void postpone_ping() {
timer_.expires_from_now(boost::posix_time::millisec(rand() %
7000));
timer_.async_wait( MEM_FN(do_ping));
}
void do_ask_clients() {
std::ostream out(&write_buf_); out << "ask_clients\n";
}
};
int main(int argc, char* argv[]) {
ip::tcp::endpoint ep( ip::address::from_string("127.0.0.1"),
8001);
talk_to_svr::start(ep, "John");
service.run();
}