代码拉取完成,页面将自动刷新
基于libuv实现的C++11风格网络库。接口简洁,性能优越,做过业务压测,稳定线上运行。正确使用接口情况下,未发现core dump或内存泄漏。
TcpServer
、TcpClient
、TcpConnection
、TcpAccept
、Udp
。DNS
和Http
:DNS查询及HTTP协议支持,基于Radix Tree支持通配符等HTTP SEVER路由机制。Timer
及TimerWheel
:定时器及时间复杂度为O(1)的心跳超时踢出机制。Async
:异步机制封装。相对于原生libuv async接口,优化了调用多次可能只运行一次的问题(特性)。由于libuv几乎所有api都非线程安全,建议使用writeInLoop接口代替直接write(writeInLoop会检查当前调用的线程,如果在loop线程中调用则直接write,否则把write加到loop线程中执行)。Packet
与PacketBuffer
:包与缓存,发送/接受包,用于从TCP字节流解析协议包。由ListBuffer和CycleBuffer两种实现(前者空间友好,后者时间友好)。提供默认Packet消息协议,也可实现自定义任意消息协议(参考uvnsq实现NSQ消息协议)。
环境:Intel Core i5 8265U + debian8 + gcc8.3.0 + libuv1.30.0 + '-O2'优化
包大小 | 1K bytes | 2K bytes | 4K bytes | 8K bytes |
---|---|---|---|---|
uv-cpp | 16138 kbyte | 32071 kbyte | 59264 kbyte | 123813 kbyte |
boost.asio | 16119 kbyte | 31566 kbyte | 58322 kbyte | 126210 kbyte |
环境:i5-8265U + 4G内存 + 4k字节ping-pong
并发数 | 10 | 100 | 1000 | 5000 |
---|---|---|---|---|
uv-cpp | 654282 kbyte | 591869 kbyte | 401500 kbyte | 412855 kbyte |
boost.asio | 633818 kbyte | 585716 kbyte | 371386 kbyte | 382402 kbyte |
环境:Intel Core i5 8265U + debian8 + gcc8.3.0 + libuv1.30.0 + '-O2'
1000 并发 && 100000 次请求和nginx对比。
十行代码实现简单echo服务
#include <iostream>
#include <uv/include/uv11.h>
int main(int argc, char** args)
{
uv::EventLoop* loop = uv::EventLoop::DefaultLoop();
uv::TcpServer server(loop);
server.setMessageCallback([](uv::TcpConnectionPtr ptr,const char* data, ssize_t size)
{
ptr->write(data, size, nullptr);
});
//server.setTimeout(60); //heartbeat timeout.
uv::SocketAddr addr("0.0.0.0", 10005, uv::SocketAddr::Ipv4);
server.bindAndListen(addr);
loop->run();
}
简单的http服务器,基于Radix Tree实现的路由机制,支持通配符、设置参数。
int main(int argc, char** args)
{
uv::EventLoop loop;
uv::http::HttpServer::SetBufferMode(uv::GlobalConfig::BufferMode::CycleBuffer);
uv::http::HttpServer server(&loop);
//example: 127.0.0.1:10010/test
server.Get("/test",std::bind(&func1,std::placeholders::_1,std::placeholders::_2));
//example: 127.0.0.1:10010/some123abc
server.Get("/some*",std::bind(&func2, std::placeholders::_1, std::placeholders::_2));
//example: 127.0.0.1:10010/value:1234
server.Get("/value:",std::bind(&func3, std::placeholders::_1, std::placeholders::_2));
//example: 127.0.0.1:10010/sum?param1=100¶m2=23
server.Get("/sum",std::bind(&func4, std::placeholders::_1, std::placeholders::_2));
uv::SocketAddr addr("127.0.0.1", 10010);
server.bindAndListen(addr);
loop.run();
}
更多的例程 here.
!对于诸如uv::Timer
,uv::TcpClient
等对象的释放需要调用close接口并在回调函数中释放对象,否则可能会出错。
!切勿在Loop线程外创建注册该Loop下的事件相关对象(uv::TcpClient
,uv::TcpServer
,uv::Timer
……),建议每个Loop都绑定独立线程运行。
一点微小的工作。
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。