///---------------------------------------------------------------------------- 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); } } }