在boost用asio设计TCP服务器的关键技术及boost用asio设计TCP服务器中单连接的设计中,整理了boost的asio设计tcp服务器的连接管理类和单连接的处理类,基本可以实现双工的多并发tcp服务器的功能了,在代码中,采用strand可以实现函数执行同步的功能。
例如,在session中发送数据的函数:
void session::start_send(char* cmd)
{
strand_.post(boost::bind(&session::_start_send,shared_from_this(),cmd));
}
实际工作的函数是_start_send,用strand去post这个函数,以保证这个函数的执行不受影响,以实现同步。
void session::_start_send(char* cmd)
{
char* wBufferPtr = (char*)write_buffer;
memset(wBufferPtr,0,max_msg);
sprintf(wBufferPtr,"%s\r\n",cmd);
socket_.async_send(boost::asio::buffer(write_buffer,strlen(wBufferPtr)),
strand_.wrap( boost::bind(&session::send_handler,
shared_from_this(),
boost::asio::placeholders::error)));
}
strand的作用是将io_service中执行的函数串行处理,所以strand的初始化也是需要传入io_service的对象,串行化的方法包括socket的send和receive,在上面的send函数中,回调的通知函数send_handler采用strand的wrap方法包裹了起来。另外,strand有post和dispatch两种方法,个人认为post更加合理。
整理一下tcp的服务器的心跳的机制,检查心跳主要在于定时器的设计,boost的异步定时机制可以将timer放到io_service中来执行。
boost::asio::deadline_timer sessionAliveTimer;
设置timer的方法为:
void session::_setTimer(int sec) {
sessionAliveTimer.expires_from_now(boost::posix_time::seconds(sec));
sessionAliveTimer.async_wait(
strand_.wrap(boost::bind(&session::_checkHeartBeat, shared_from_this(), boost::asio::placeholders::error, &sessionAliveTimer))
);
}
含义为根据sec设置下一次定时到达的时间间隔,到了这个时间间隔执行_checkHeartBeat函数。
void session::_checkHeartBeat(const boost::system::error_code& /*e*/, boost::asio::deadline_timer* t)
{
printf("sessionId:%d; heartbeat_count_:%d.\n",sessionId, heartbeat_count_);
_setTimer(2);
}
通过_checkHeartBeat函数的调用_setTimer(2),实现了异步循环定时检测心跳的结构。