发布一个参考tornado的高性能c++网络库:libtnet
libtnet是一个用c++编写的高性能网络库,它在设计上面主要参考tornado,为服务端网络编程提供简洁而高效的接口,非常易于使用。
Echo Server
void onConnEvent(const ConnectionPtr_t& conn, ConnEvent event, const void* context)
{
switch(event)
{
case Conn_ReadEvent:
{
const StackBuffer* buffer = static_cast<const StackBuffer*>(context);
conn->send(string(buffer->buffer, buffer->count));
}
break;
default:
break;
}
}
int main()
{
TcpServer s;
s.listen(Address(11181), std::bind(&onConnEvent, _1, _2, _3));
s.start();
return 0;
}
当程序启动,服务监听本地11181端口,我们使用telnet测试:
root@tnet:~# telnet 127.0.0.1 11181
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
hello world
hello world
可以看到,libtnet在使用上面非常简单,在listen的时候,指定一个回调函数,当有新的连接到来的时候,该回调函数就会与该connection进行绑定,这样该connection的任何事件都能通过回调进行处理。
在上面那个例子中,我们只关心了connection的ReadEvent,也就是读事件,然后将读取到的所有数据原封不动的转发回去。
Http Server
void onHandler(const HttpConnectionPtr_t& conn, const HttpRequest& request)
{
HttpResponse resp;
resp.statusCode = 200;
resp.body.append("Hello World");
conn->send(resp);
}
int main()
{
TcpServer s;
HttpServer httpd(&s);
httpd.setHttpCallback("/abc", std::bind(&onHandler, _1, _2));
httpd.listen(Address(11181));
s.start(4);
return 0;
}
当server启动,程序使用本机11181端口提供http服务。我们使用curl测试。
curl http://127.0.0.1:11181/abc
return: hello world
可以看到,使用http server也非常简单,我们只需要对相应的路径绑定一个callback回调,当有请求发生的时候,对应的callback执行。
使用benchmark测试,发现性能也不错RPS能到16000+,在512MB,单核CPU下面进行ab压测,具体可以参考benchmark。
Webscoket Server
void onWsCallback(const WsConnectionPtr_t& conn, WsEvent event, const void* context)
{
switch(event)
{
case Ws_MessageEvent:
{
const string& str = *(const string*)context;
conn->send("hello " + str);
}
break;
default:
break;
}
}
int main()
{
TcpServer s;
HttpServer httpd(&s);
httpd.setWsCallback("/push/ws", std::bind(&onWsCallback, _1, _2, _3));
httpd.listen(Address(11181));
s.start();
return 0;
}
libtnet同样提供了websocket RFC6455的支持,使用方法同http server,只需要对相应的path注册特定的回调,就可以很方便的进行websocket交互。
Client
libtnet不光提供了server层面的相关功能,同时也集成了http client,websocket client以及redis client。使得libtnet也能方便的进行客户端网络功能的开发。对于具体的使用,可以参考example。
设计上面的考量
libtnet只支持linux版本,虽然做一个跨平台的通用库是一件吸引力非常大的事情,但是综合考虑之后,我决定只做linux版本的,主要有以下几个原因:
- Linux下面使用prefork + epoll是一种非常高效的网络编程模型,性能强悍,实现简单。虽然unix下面有kqueue,windows下面有IOCP,但是没必要为了适配所有得操作系统将代码写的复杂。
- Linux在系统层面上面就提供了很多高性能的函数,譬如timerfd,eventfd等,不光性能提升,同时也简化了很多代码实现。
- Linux在服务器编程领域的使用率很高,专门做精一个平台就够了。
因为高性能的网络编程通常都是使用异步的编程方式,所以经常可以看到代码被异步拆的特别分散,不利于编写。所以我在libtnet里面大量的使用了c++ bind以及shared_ptr技术,用来模拟函数闭包,以及解决对象生命周期管理问题,简化代码的编写。并且我也使用了c++ 0x相关技术,gcc的版本至少要在4.4以上。
对于如何设计以及使用libtnet,后续我会有更加详细的说明。项目地址https://github.com/siddontang/libtnet,欢迎大家围观。
发布一个参考tornado的高性能c++网络库:libtnet的更多相关文章
- 高性能C++网络库libtnet实现:IOLoop
IOLoop libtnet采用的是prefork + event loop的架构方式,prefork就是server在启动的时候预先fork多个子进程同时工作,而event loop则是基于epol ...
- 高性能C++网络库libtnet实现:http
HTTP libtnet提供了简单的http支持,使用也很简单. 一个简单的http server: void onHandler(const HttpConnectionPtr_t& con ...
- 高性能C++网络库libtnet实现:Connection
Connection libtnet只支持IPv4 TCP Connection,之所以这么做都是为了使得实现尽可能的简单.我们主要在Connection类中封装了对tcp连接的操作. Connect ...
- 高性能C++网络库libtnet实践:comet单机百万连接挂载测试
最近在用go语言做一个挂载大量长连接的推送服务器,虽然已经完成,但是内存占用情况让我不怎么满意,于是考虑使用libtnet来重新实现一个.后续我会使用comet来表明推送服务器. 对于comet来说, ...
- 公布一个基于 Reactor 模式的 C++ 网络库
公布一个基于 Reactor 模式的 C++ 网络库 陈硕 (giantchen_AT_gmail) Blog.csdn.net/Solstice 2010 Aug 30 本文主要介绍 muduo 网 ...
- 发布一个参考ssdb,用go实现的类似redis的高性能nosql:ledisdb
起因 ledisdb是一个参考ssdb,采用go实现,底层基于leveldb,类似redis的高性能nosql数据库,提供了kv,list,hash以及zset数据结构的支持. 我们现在的应用极大的依 ...
- 基于c++11新标准开发一个支持多线程高并发的网络库
背景 新的c++11标准出后,c++语法得到了非常多的扩展,比起以往不论什么时候都要灵活和高效,提高了程序编码的效率,为软件开发者节省了不少的时间. 之前我也写过基于ACE的网络server框架,但A ...
- 发布一个参考ssdb,使用go类似的实现redis高性能nosql:ledisdb
起因 ledisdb是一个參考ssdb.採用go实现,底层基于leveldb,相似redis的高性能nosql数据库,提供了kv,list,hash以及zset数据结构的支持. 我们如今的应用极大的依 ...
- 从零开始构建一个Reactor模式的网络库(一) 线程同步Mutex和Condition
最近在学习陈硕大神的muduo库,感觉写的很专业,以及有一些比较“高级”的技巧和设计方式,自己写会比较困难. 于是打算自己写一个简化版本的Reactor模式网络库,就取名叫mini吧,同样只基于Lin ...
随机推荐
- cassandra 3.x官方文档(6)---内部原理之存储引擎
写在前面 cassandra3.x官方文档的非官方翻译.翻译内容水平全依赖本人英文水平和对cassandra的理解.所以强烈建议阅读英文版cassandra 3.x 官方文档.此文档一半是翻译,一半是 ...
- React Native 项目实战-Tamic
layout: post title: React Native 项目实战 date: 2016-10-18 15:02:29 +0800 comments: true categories: Rea ...
- JFinal中使用QuartzPlugin报ClassCastException解决方法
JDK1.8中泛型反射修改对旧版本的影响 本文地址:http://blog.csdn.net/sushengmiyan 本文作者:苏生米沿 问题复现环境: JDK1.8 JFinal1.9 quart ...
- [BBS]搭建开源论坛之JForum安装使用札记
本文作者:sushengmiyan 本文地址:http://blog.csdn.net/sushengmiyan/article/details/47761303 目录 目录 BBS搭建开源论坛之JF ...
- MySQL命令行SQL脚本的导入导出小结(数据库的备份与还原)
1.设置环境变量 要想在命令行下各处都能执行mysql命令,必须在系统变量Path中添加mysql的命令所在的目录.例如我安装的是集成PHP环境的mysql,在D盘xampps下,则我需要将" ...
- Linux测量kernel子模块加载时间的方法
1. 在文件kernel/init/main.c里面,在接口do_one_initcall( )中,将initcall_debug设置为true,然后编译boot.img 2. 使用adb shell ...
- java中八种基本数据类型以及它们的封装类,String类型的一些理解
在我们面试或者考试过程中经常会考到八种基本数据类型以及它们的封装类,那么有哪八种基本数据类型呢?它们的封装类又是什么呢? 首先,八种基本数据类型分别是:int.short.float.double.l ...
- Java并发框架——AQS中断的支持
线程的定义给我们提供了并发执行多个任务的方式,大多数情况下我们会让每个任务都自行执行结束,这样能保证事务的一致性,但是有时我们希望在任务执行中取消任务,使线程停止.在java中要让线程安全.快速.可靠 ...
- Hadoop介绍
是适合大数据的分布式存储与计算平台,用java编写的开源系统,能够安排在大规模的计算机平台上,从而长进计算效率:由 HDFS.MapReduce.HBase.Hive 和 ZooKeeper等成员组成 ...
- Python 键盘鼠标监听
异想天开的想记录一下自己每天的键盘键位走向,于是就在网上搜索了一下相关的实现,然后就发现了一个第三方的库pyHook.封装的很好,我们只需要傻瓜式的调用里面的API就可以了. 下面是我在使用pyHoo ...