Пример #1
0
  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"));
  }
Пример #2
0
///----------------------------------------------------------------------------
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")));
  }
Пример #3
0
  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;
    }
  }
Пример #4
0
  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;
    }
  }
Пример #5
0
///----------------------------------------------------------------------------
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);
      }
    }
Пример #6
0
///----------------------------------------------------------------------------
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);
        }
      }
    }