void run(gce::actor<gce::stackful>& self, gce::aid_t base_id) { try { /// wait 1 second for server setup gce::wait(self, gce::seconds_t(1)); /// make a tcp socket to connnect to server gce::yield_t yield = self.get_yield(); gce::io_service_t& ios = ctx_.get_io_service(); boost::asio::ip::tcp::resolver reso(ios); boost::asio::ip::tcp::resolver::query query(host_, port_); boost::asio::ip::tcp::resolver::iterator itr = reso.async_resolve(query, yield); boost::asio::ip::tcp::socket sock(ios); boost::asio::async_connect(sock, itr, yield); char data[32]; for (std::size_t i=0; i<echo_num_; ++i) { boost::asio::async_write(sock, boost::asio::buffer(data, 32), yield); boost::asio::async_read(sock, boost::asio::buffer(data, 32), yield); /// per second a echo gce::wait(self, gce::seconds_t(1)); } } catch (std::exception& ex) { std::cerr << ex.what() << std::endl; } gce::send(self, base_id, gce::atom("done")); }
///---------------------------------------------------------------------------- void quit_callback( gce::actor<gce::stackful>& self, std::vector<gce::aid_t>& conn_group_list ) { std::vector<gce::resp_t> res_list; BOOST_FOREACH(gce::aid_t aid, conn_group_list) { res_list.push_back(self.request(aid, gce::atom("stop"))); }
void run(gce::actor<gce::stackful>& self) { try { gce::yield_t yield = self.get_yield(); gce::io_service_t& ios = ctx_.get_io_service(); boost::asio::ip::address addr; addr.from_string(host_); boost::asio::ip::tcp::endpoint ep(addr, port_); acpr_.open(ep.protocol()); acpr_.set_option(boost::asio::socket_base::reuse_address(true)); acpr_.bind(ep); acpr_.set_option(boost::asio::socket_base::receive_buffer_size(640000)); acpr_.set_option(boost::asio::socket_base::send_buffer_size(640000)); acpr_.listen(1024); acpr_.set_option(boost::asio::ip::tcp::no_delay(true)); acpr_.set_option(boost::asio::socket_base::keep_alive(true)); acpr_.set_option(boost::asio::socket_base::enable_connection_aborted(true)); while (true) { gce::errcode_t ec; boost::shared_ptr<socket_t> sock(new socket_t(ios)); acpr_.async_accept(*sock, yield[ec]); if (!ec) { std::cout << "new connection!\n"; gce::spawn(self, boost::bind(&server::session, this, _1, sock)); } else { break; } } } catch (std::exception& ex) { std::cerr << ex.what() << std::endl; } }
void session(gce::actor<gce::stackful>& self, boost::shared_ptr<socket_t> sock) { try { gce::yield_t yield = self.get_yield(); char data[32]; for (std::size_t i=0; i<echo_num_; ++i) { boost::asio::async_read(*sock, boost::asio::buffer(data, 32), yield); boost::asio::async_write(*sock, boost::asio::buffer(data, 32), yield); } std::cout << "echo done!\n"; } catch (std::exception& ex) { std::cerr << ex.what() << std::endl; } }
///---------------------------------------------------------------------------- void user::run( gce::actor<gce::stackful>& self, app_ctxid_list_t game_list, gce::aid_t old_usr_aid, gce::aid_t master, cid_t cid, std::string username, std::string passwd ) { try { if (old_usr_aid) { /// verify username and passwd, if valid then kick old session gce::resp_t res = gce::request(self, old_usr_aid, gce::atom("kick")); gce::recv(self); } else { /// check db/cache if username existed /// if existed, verify username and passwd; or register } /// verify or register ok, link cid; self.link(cid); /// response cln_login ok or error gce::aid_t sender = gce::recv(self, gce::atom("cln_login")); gce::reply(self, sender, gce::atom("ok"), std::string()); /// loop handle messages bool running = true; while (running) { gce::message msg; gce::aid_t sender = self.recv(msg); gce::match_t type = msg.get_type(); if (type == gce::exit) { running = false; } else if (type == gce::atom("kick")) { running = false; gce::reply(self, sender, gce::atom("ok")); } else if (type == gce::atom("chat")) { gce::message m(gce::atom("fwd_msg")); m << msg; self.send(cid, m); } else if (type == gce::atom("chat_to")) { std::string target; msg >> target; if (target != username) { /// find game app and send chat msg gce::svcid_t game_svcid = select_game_app(game_list, target); self.send(game_svcid, msg); } else { /// send to self gce::message m(gce::atom("fwd_msg")); m << msg; self.send(cid, m); } } else if (type == gce::atom("cln_logout")) { running = false; } else { std::string errmsg("user::run unexpected message, type: "); errmsg += gce::atom(type); throw std::runtime_error(errmsg); } }
///---------------------------------------------------------------------------- void conn::run(gce::actor<gce::stackless>& self) { try { GCE_REENTER (self) { GCE_YIELD { gce::response_t res = gce::request( self, group_aid_, gce::atom("add_conn") ); self.recv(res, sender_, msg_); } if (msg_.get_type() != gce::atom("ok")) { throw std::runtime_error("add_conn error"); } GCE_YIELD { gce::spawn( self, boost::bind(&conn::timeout::run, &tmo_, _1), tmo_aid_, gce::monitored ); } GCE_YIELD { gce::spawn( self, boost::bind( &conn::recv::run, &rcv_, _1, tmo_aid_, self.get_aid() ), rcv_aid_, gce::monitored, true ); } running_ = true; exit_num_ = 0; while (running_) { msg_ = gce::message(); sender_ = gce::aid_t(); GCE_YIELD self.recv(sender_, msg_); type_ = msg_.get_type(); if (type_ == gce::exit) { ++exit_num_; if (exit_num_ < 2) { gce::send(self, tmo_aid_, gce::exit); skt_->close(); } else { running_ = false; } } else if (type_ == gce::atom("stop")) { gce::send(self, tmo_aid_, gce::exit); skt_->close(); } else if (type_ == gce::atom("fwd_msg")) { GCE_YIELD { gce::message m; msg_ >> m; std::printf("fwd msg to client: %s\n", gce::atom(m.get_type()).c_str()); ec_.clear(); skt_->send(m, gce::adaptor(self, ec_, bytes_transferred_)); } if (ec_) { throw std::runtime_error("socket send error"); } } else { std::string errmsg("conn::run unexpected message, type: "); errmsg += gce::atom(type_); throw std::runtime_error(errmsg); } } }