#handy yedongfu
Handy是一个简洁高效的C++11网络库,支持linux与mac平台,使用异步IO模型
使用示例
EventBase事件分发器
tcp连接
tcp服务器
http服务器
using namespace std; using namespace handy;
int main(int argc, const char* argv[]) { EventBase base; //事件分发器 //注册Ctrl+C的信号处理器--退出事件分发循环 Signal::signal(SIGINT, [&]{ base.exit(); }); TcpServer echo(&base); //创建服务器 int r = echo.bind("", 99); //绑定端口 exitif(r, "bind failed %d %s", errno, strerror(errno)); echo.onConnRead([](const TcpConnPtr& con) { con->send(con->getInput()); // echo 读取的数据 }); base.loop(); //进入事件分发循环 }
<h2 id="event-base">EventBase事件分发器</h2>
EventBase是事件分发器,内部使用epoll/kqueue来管理异步IO
```c
EventBase base;
###事件分发循环
//不断调用epoll_wait,处理IO事件
base.loop();
###退出事件循环
//退出事件循环,可在其他线程中调用
base.exit();
###是否已退出
bool exited();
###管理客户端连接
TcpConnPtr con = TcpConn::createConnection(&base, host, port);
###管理tcp服务器的所有socket
TcpServer echo(&base);
###在IO线程中执行任务 一些任务必须在IO线程中完成,例如往连接中写入数据。非IO线程需要往连接中写入数据时,必须把任务交由IO线程进行处理
void safeCall(const Task& task);
base.safeCall([](con){con->send("OK");});
###管理定时任务 EventBase通过设定epoll_wait/kevent的等待时间让自己及时返回,然后检查是否有到期的任务,因此时间精度依赖于epoll_wait/kevent的精度
//interval: 0:一次性任务;>0:重复任务,每隔interval毫秒,任务被执行一次
TimerId runAfter(int64_t milli, const Task& task, int64_t interval=0);
//runAt则指定执行时刻
TimerId runAt(int64_t milli, const Task& task, int64_t interval=0)
//取消定时任务,若timer已经过期,则忽略
bool cancel(TimerId timerid);
TimerId tid = base.runAfter(1000, []{ info("a second passed"); });
base.cancel(tid);
//连接空闲30s关闭连接 con->addIdleCB(30, [](const TcpConnPtr& con)) { con->close(); });
###消息模式
可以使用onRead处理消息,也可以选用onMsg方式处理消息
```c
//消息回调,此回调与onRead回调只有一个生效,后设置的生效
//codec所有权交给onMsg
void onMsg(CodecBase* codec, const MsgCallBack& cb);
//发送消息
void sendMsg(Slice msg);
con->onMsg(new LineCodec, [](const TcpConnPtr& con, Slice msg) {
info("recv msg: %.*s", (int)msg.size(), msg.data());
con->sendMsg("hello");
});
###存放自定义数据
template<class T> T& context();
con->context<std::string>() = "user defined data";
chat.onConnCreate([&]{ TcpConnPtr con(new TcpConn); con->onState([&](const TcpConnPtr& con) { if (con->getState() == TcpConn::Connected) { con->context() = 1; } } return con; });
<h2 id="http-server">HttpServer http服务器</h2>
```c
//使用示例
HttpServer sample(&base);
int r = sample.bind("", 8081);
exitif(r, "bind failed %d %s", errno, strerror(errno));
sample.onGet("/hello", [](const HttpConnPtr& con) {
HttpResponse resp;
resp.body = Slice("hello world");
con.sendResponse(resp);
});
持续更新中......