如何在120行内实现一个有协程并支持tbus的服务器框架
来源:互联网 发布:碧海潮生曲 知乎 编辑:程序博客网 时间:2024/06/05 02:53
目前协程很火,于是决定搞一个框架试试,下面的代码很短,不过麻雀虽小,五脏俱全。目前支持tbus,配上boost::asio,可以很容易的支持tcp,udp,异步文件读写等操作。
附linux下编译指令:
g++ server.cpp -I$(BOOST_ROOT) -o server \
$(BOOST_ROOT)/stage/lib/libboost_coroutine.a\
$(BOOST_ROOT)/stage/lib/libboost_context.a\
$(BOOST_ROOT)/stage/lib/libboost_system.a\
$(BOOST_ROOT)/stage/lib/libboost_thread.a -lpthread -lrt
#include <boost/asio.hpp>#include <boost/coroutine/all.hpp>#include <boost/bind.hpp>#include <boost/thread.hpp>#include <boost/chrono.hpp>#include <boost/shared_ptr.hpp>namespace ba = boost::asio;class fake_tbus{public:fake_tbus():m_trans_id(0),m_msg("initial request"){}void tbus_send(int trans_id, std::string buf){m_trans_id = trans_id;m_msg = buf;std::cout << "tbus_send: " << trans_id << ": " << m_msg << std::endl;}std::string tbus_recv(int& trans_id){trans_id = m_trans_id;std::cout << "tbus_recv: " << trans_id << ": " << m_msg << std::endl;return m_msg;}private:int m_trans_id;std::string m_msg;};class server{public:typedef boost::coroutines::asymmetric_coroutine<std::string>::push_type push_type;typedef boost::coroutines::asymmetric_coroutine<std::string>::pull_type pull_type;typedef boost::shared_ptr<push_type> push_type_ptr;typedefstd::map<int, push_type_ptr> coroutine_map_t;;server():m_stop(false){}void run(){int global_trans_id = 0;while (!m_stop){int tbus_trans_id = 0;std::string buf = m_tbus.tbus_recv(tbus_trans_id);push_type_ptr p_push;// this is an new request, so we create a new coroutine.if (tbus_trans_id == 0){global_trans_id++;p_push.reset(new push_type(boost::bind(&server::tbus_handler, this, global_trans_id, _1)));m_coroutines.insert(std::make_pair(global_trans_id, p_push)); tbus_trans_id = global_trans_id;}// this should be in a transaction, find the coroutine dealing with it.else{coroutine_map_t::iterator it = m_coroutines.find(tbus_trans_id);if (it != m_coroutines.end()){p_push = it->second;}}if (p_push){// to the next step.bool has_next = (*p_push)(buf);if (!has_next){// if coroutine has returnd, finish it.m_coroutines.erase(tbus_trans_id);}}boost::this_thread::sleep_for(boost::chrono::seconds(1));}}// our handler function.void tbus_handler(int trans_id, pull_type& pull){std::string req = get_request(pull);std::cout << "tbus_handler req: " << req << std::endl;std::string res = yield_async_send(trans_id, pull, "hello");std::cout << "tbus_handler res1: " << res << std::endl;res = yield_async_send(trans_id, pull, "world");std::cout << "tbus_handler res2: " << res << std::endl;}std::string yield_async_send(int trans_id, pull_type& pull, std::string buf){m_tbus.tbus_send(trans_id, buf);pull();return pull.get();} std::string get_request(pull_type& pull){return pull.get();} coroutine_map_t m_coroutines;bool m_stop;fake_tbus m_tbus;};int main(int argc, char* argv[]){server s;s.run();return 0;}/*输出:tbus_recv: 0: initial requesttbus_handler req: initial requesttbus_send: 1: hellotbus_recv: 1: hellotbus_handler res1: hellotbus_send: 1: worldtbus_recv: 1: worldtbus_handler res2: worldtbus_recv: 1: worldtbus_recv: 1: worldtbus_recv: 1: worldtbus_recv: 1: worldtbus_recv: 1: world*/
0 0
- 如何在120行内实现一个有协程并支持tbus的服务器框架
- 一个支持RunGate的服务器框架实例
- 一个支持RunGate的服务器框架实例(转)
- ACEXML解析XML文件——我是如何学习并在短时间内掌握一个库的使用方法的
- 如何在页面内制作一个可以实现'另存为'的链接
- 3.2如何选择是在 视图类 还是在 视图的框架窗口类 内实现某种特殊行为?
- 自己实现一个简单的支持并发的Web服务器
- 如何实现一个简单的rpc框架
- 如何在20分钟内写一个成功的博客
- 在网页frameset结构中,如何在框架内的页面访问框架
- 如何在局域网内组建一个时间服务器
- 如何在局域网内部署服务器监控 ?
- 实现一个同步的并发型TCP服务器
- 在一个TabHost内实现多个Activity的跳转
- 在一个TabHost内实现多个Activity的跳转
- 在一个TabHost内实现多个Activity的跳转
- 如何实现一个支持共享内存的Map或Set
- 用Reactor框架实现一个简单的tcp服务器
- Search a 2D Matrix
- PHP 数组运算符
- (二)设计模式之UML六大关系
- 实现和IE浏览器交互的几种方法的介绍(二)
- 修改npm包管理器的registry为淘宝镜像(npm.taobao.org)
- 如何在120行内实现一个有协程并支持tbus的服务器框架
- 单源最短路径--Dijkstra
- DragGridView使用
- 初识ps君记录~~
- 如何转换一些常见的文档格式
- 2015暑假集训总结
- mysql grant
- Android操作HTTP实现与服务器通信
- Hdu Oj 2112 HDU Today