高性能C++网络库libtnet实现:http
HTTP
libtnet提供了简单的http支持,使用也很简单。
一个简单的http server:
void onHandler(const HttpConnectionPtr_t& conn, const HttpRequest& request)
{
    HttpResponse resp;
    resp.statusCode = 200;
    resp.setContentType("text/html");
    resp.body.append("Hello World");
    conn->send(resp);
}
TcpServer s;
HttpServer httpd(&s);
httpd.setHttpCallback("/test", std::bind(&onHandler, _1, _2));
httpd.listen(Address(80));
s.start(4);
我们对http server的"/test"注册了一个handler,当用户访问该url的时候,就会显示"Hello World"。
同样,http client的使用也很简单:
void onResponse(IOLoop* loop, const HttpResponse& resp)
{
    cout << resp.body << endl;
    loop->stop();
}
IOLoop loop;
HttpClientPtr_t client = std::make_shared<HttpClient>(&loop);
client->request("http://127.0.0.1:80/test", std::bind(&onResponse, &loop, _1));
loop.start();
这里,我们使用了一个http client,向server请求"/test"的内容,当服务器有响应之后,会调用响应的回调函数。
HTTP Parser
对于http的解析,我采用的是http parser,因为它采用的是流式解析,同时非常容易集成进libtnet。
使用http parser只需要设置相应的回调函数即可。http parser有如下几种回调:
- message begin,解析开始的时候调用
 - url,解析url的时候调用
 - status complete,http response解析status的时候调用
 - header field,解析http header的field调用
 - header value,解析http header的value调用
 - headers complete,解析完成http header调用
 - body,解析http body调用
 - message complete,解析完成调用
 
这里特别需要注意的是http header的解析,因为http parser将其拆分成了两种回调,所以我们在处理的时候需要记录上一次header callback是field的还是value的。在解析field的时候,如果上一次是value callback,那我们就需要将上一次解析的field和value保存下来,而该次的解析则是一个新的field了。
另外,http parser还提供了upgrade的支持,所以我们很方便的就能区分该次请求是否为websocket。
Websocket
libtnet也提供了websocket的支持,现阶段,只支持RFC6455。
当libtnet通过http parser发现该次请求为websocket的时候,就进入了websocket的流程。websocket的使用也很简单,当握手成功之后,后续的所有通讯就是纯粹的tcp通信了。
一个简单的websocket server:
void onWsCallback(const WsConnectionPtr_t& conn, WsEvent event, const void* context)
{
    switch(event)
    {
        case Ws_CloseEvent:
            break;
        case Ws_MessageEvent:
            {
                const string& str = *(const string*)context;
                conn->send(str);
            }
            break;
        case Ws_PongEvent:
            break;
        default:
            break;
    }
}
TcpServer s;
HttpServer httpd(&s);
httpd.setWsCallback("/push/ws", std::bind(&onWsCallback, _1, _2, _3));
httpd.listen(Address(80));
s.start();
可以看到,websocket的callback机制也类似于libtnet connection的callback机制,用户需通过event + context的方式来处理该次回调的数据。
libtnet对websocket的frame的处理参照的是tornado的websocket模块。也能够组合多frame的数据,外部只需要关注Ws_MessageEvent即可。
websocket client的实现也很简单:
void onWsConnEvent(const WsConnectionPtr_t& conn, WsEvent event, const void* context)
{
    switch(event)
    {
        case Ws_OpenEvent:
            conn->send("Hello world");
            break;
        case Ws_MessageEvent:
            {
                const string& msg = *(const string*)context;
                LOG_INFO("message %s", msg.c_str());
                conn->close();
            }
            break;
        default:
            break;
    }
}
IOLoop loop;
WsClientPtr_t client = std::make_shared<WsClient>(&loop);
client->connect("ws://127.0.0.1:80/push/ws", std::bind(&onWsConnEvent, _1, _2, _3));
loop.start();
libtnet的地址https://github.com/siddontang/libtnet,欢迎围观。
高性能C++网络库libtnet实现:http的更多相关文章
- 高性能C++网络库libtnet实现:Connection
		
Connection libtnet只支持IPv4 TCP Connection,之所以这么做都是为了使得实现尽可能的简单.我们主要在Connection类中封装了对tcp连接的操作. Connect ...
 - 高性能C++网络库libtnet实践:comet单机百万连接挂载测试
		
最近在用go语言做一个挂载大量长连接的推送服务器,虽然已经完成,但是内存占用情况让我不怎么满意,于是考虑使用libtnet来重新实现一个.后续我会使用comet来表明推送服务器. 对于comet来说, ...
 - 高性能C++网络库libtnet实现:IOLoop
		
IOLoop libtnet采用的是prefork + event loop的架构方式,prefork就是server在启动的时候预先fork多个子进程同时工作,而event loop则是基于epol ...
 - 发布一个参考tornado的高性能c++网络库:libtnet
		
libtnet是一个用c++编写的高性能网络库,它在设计上面主要参考tornado,为服务端网络编程提供简洁而高效的接口,非常易于使用. Echo Server void onConnEvent(co ...
 - 专注于HTTP的高性能高易用性网络库:Fslib.network库
		
博客列表页:http://blog.fishlee.net/tag/fslib-network/ 原创FSLib.Network库(目前专注于HTTP的高性能高易用性网络库) FSLib.Networ ...
 - [开源] gnet: 一个轻量级且高性能的 Golang 网络库
		
Github 主页 https://github.com/panjf2000/gnet 欢迎大家围观~~,目前还在持续更新,感兴趣的话可以 star 一下暗中观察哦. 简介 gnet 是一个基于 Ev ...
 - Cowboy 开源 WebSocket 网络库
		
Cowboy.WebSockets 是一个托管在 GitHub 上的基于 .NET/C# 实现的开源 WebSocket 网络库,其完整的实现了 RFC 6455 (The WebSocket Pro ...
 - 开源免费的C/C++网络库(c/c++ sockets library)
		
(1)ACE 庞大.复杂,适合大型项目.开源.免费,不依赖第三方库,支持跨平台. http://www.cs.wustl.edu/~schmidt/ACE.html (2)Asio Asio基于Boo ...
 - poco网络库分析,教你如何学习使用开源库
		
Poco::Net库中有 FTPClient HTML HTTP HTTPClient HTTPServer ICMP Logging Mail Messages NetCore NTP OAuth ...
 
随机推荐
- ORA-01207: file is more recent than control file - old control file的处理方法
			
1. 连接数据库 sqlplus / as sysdba2. 启动数据库,此时会报标题中的错误startup 3.备份创建控制文件的脚本语句,并从中拷贝出相关的NORESETLOGS模式的创建控制文件 ...
 - C++笔记010:C++对C的扩展——register关键字增强
			
register关键字:请求编译器让变量直接放到CPU内部寄存器里面,而不是通过内存寻址访问,速度快. 在C语言中,register修饰的变量不能取地址,去寄存器变量的地址在C语言里面是会出错的. i ...
 - jQuery 效果 – 停止动画
			
jQuery stop() 方法用于在动画或效果完成前对它们进行停止. 点击这里,向上/向下滑动面板 实例 jQuery stop() 滑动 演示 jQuery stop() 方法. jQuery s ...
 - 让你的代码量减少3倍!使用kotlin开发Android(三) 缩短五倍的Java Bean
			
回顾一下 哈,没想到你已经坚持不懈看到第三篇了,不错哈~坚持就是胜利. 本文同步自博主的私人博客wing的地方酒馆 在上一篇文章中,我们介绍了扩展函数,这里对上一篇进行一点小小的补充. 还记得text ...
 - IT男的别样人生,爱折腾,竟然辞职跑丽江去了
			
深圳待了4年,在深圳腾讯总部任职,北漂了5年多,任某知名团购公司CTO,有了孩子以后才知道自己想要什么 2015年4月,我和老婆还有6个月的儿子丽江游, 却在旅行的第四天, 买下了位于束河古镇正门的高 ...
 - Unity UGUI图文混排(七) -- 下划线
			
之前更新超链接的时候,忘了搭配实现一个下划线的功能,这篇文章就是来补上这一个功能,时间有点长,一方面没有很好的思路,一方面也没多少时间. 先在网上收集了一下下划线的实现操作,一种是在文本下再创建一个文 ...
 - android 调试工具ADB命令详解
			
adb是什么? adb的全称为Android Debug Bridge,就是起到调试桥的作用. 通过adb我们可以在Eclipse中方面通过DDMS来调试Android程序,说白了就是debug工具. ...
 - Python Generator 运行细节验证
			
今天来__next__和send, 改天来throw和close class A: def __setattr__(self, key, val): print('set %s to %s'%(key ...
 - (一二七)NSURLSession的基本用法 下载与数据获取
			
简介 NSURLSession是苹果官方提供的一系列网络接口库,使用他们可以轻松实现下载和数据获取等任务.在上一篇文章中,我们介绍了使用NSURLConnection下载文件和断点续传的功能,实现起来 ...
 - 剑指Offer——回溯算法
			
剑指Offer--回溯算法 什么是回溯法 回溯法实际是穷举算法,按问题某种变化趋势穷举下去,如某状态的变化用完还没有得到最优解,则返回上一种状态继续穷举.回溯法有"通用的解题法"之 ...