Program/C & C++

[boost] boost::asio::deadline_timer 를 이용한 timeout 설정

너구리V 2013. 3. 28. 16:25

boost asio를 이용한 네트웍 개발을 할경우에 일정시간동안 통신을 하지 않은 불필요한 세션이 존재할경우

 

해당 세션 객체를 제거를 해야된다. 불필요하게 세션이 물려서 쌓여 있을 경우!!!서버쪽에서는 부담이다.

 

이를 해결 위해 방법은 여러가지로 존재한다. 간단한 방법으론 쓰레드를 따로 두어서 expired time이 초과한 객체를 검색하여

 

제거를 하면 된다. 그렇지만 이 방법은 boost를 사용하지 않은 네트웍 모델에서는 불필요하게 쓰레드를 생성하고 동기화 작업까지

 

포함하면 비용이 만만치 않게 된다. 그래서 필자의 말은 즉 boost에서 제공해주는

 

boost::asio::deadline_timer를 사용한 예제를 설명하고자 한다.

 

#include <boost/asio.hpp>
#include <boost/bind.hpp>

#include <boost/enable_shared_from_this.hpp>

#include <boost/asio/deadline_timer.hpp>

 

class Session : private boost::noncopyable, public boost::enable_shared_from_this<Session>{

public:

...

virtual void read(unsigned char* read_buffer, size_t read_buffer_size);

virtual void on_check_read_deadline(const boost::system::error_code& error);

...

private:

...

boost::asio::deadline_timer read_deadline_timer_;

Server& server_;
TCP::socket socket_;

...

};

Session::Session(boost::asio::io_service& io_service, Server& server, SessionKey session_key)
 : server_(server)
 , socket_(io_service)
 , read_deadline_timer_(io_service)
{

...

}

void Session::read(unsigned char* read_buffer, size_t read_buffer_size)
{

// 타임아웃 시간 설정

read_deadline_timer_.expires_from_now(boost::posix_time::seconds(seconds));
  read_deadline_timer_.async_wait(boost::bind(&Session::on_check_read_deadline, shared_from_this(),boost::asio::placeholders::error));
  is_check_read_timeout_ = true;
 
 socket().async_read_some(boost::asio::buffer(read_buffer, read_buffer_size)
       ,boost::bind(&Session::handle_read, shared_from_this(),
           boost::asio::placeholders::error,
           boost::asio::placeholders::bytes_transferred
           )
       );

}

 

void Session::on_check_read_deadline(const boost::system::error_code& error)
{

// 타임아웃 체크
 if (read_deadline_timer_.expires_at() <= boost::asio::deadline_timer::traits_type::now())
 {

  close();
  return ; 
 }
 read_deadline_timer_.async_wait(boost::bind(&Session::on_check_read_deadline, shared_from_this(),boost::asio::placeholders::error));

}

 

 

boost::asio::deadline_timer 객체는 위의 예제의 생성자 부분을 보면 알 수 있듯이 boost::asio::ioservice객체 내부에서 관리해서 callback형식으로 함수를 호출해주게 된다. read함수에서 read하기전에 해당 timer를 동작을 시키고, on_check_read_deadline함수를 통해 타임아웃을 체크하여 객체를 close하게끔하는데 위의 소스의 목적이다.

반응형