libevet异步发送消息的原理
说明
代码未验证,只设计其逻辑, 工作中是成功的,不能给出.
- 类似场景:
单线程的网络库 csharp的UI异步线程 Andorid的UI异步通知 - 凡是单线程业务通知,都有其自定义通知的过程, 然后在自定义通知逻辑中实现遍历具体的单线程任务中模块(IO, UI布局等), 得到后进行操作.
逻辑
通过参考libevent源码,采用socketpair
static evutil_socket_t pair[2]; //[0]发送 [1]接收
struct evhttp* http = NULL;
struct event* evpair = NULL; //单独的io socket
//http的构建过程忽略
if (evutil_socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1)
return (1);
evutil_make_socket_nonblocking(pair[0]);
evutil_make_socket_nonblocking(pair[1]);
evpair = event_new(base, pair[1], EV_READ | EV_PERSIST, _pair_callbk, http);
if (event_add(evpair, NULL))
goto err;
static void _pair_callbk(evutil_socket_t fd, short event, void* arg)
{
char buf[256] = { 0 };
int len;
struct evhttp* http = (struct evhttp*)arg;
len = recv(fd, buf, sizeof(buf), 0);
TAILQ_FOREACH(evcon, &http->connections, next)
{
TAILQ_FOREACH(req, &evcon->requests, next)
{
evhttp_send_reply(req, 200, "OK", buff);
}
}
}
进行c++11多线程处理回复
std::vector<std::function<void(struct evhttp_request*)>> funcs;
std::thread td([]{
sleep(8); //8秒的耗时操作
//这里需要给指定的req发送消息
std::string msg="hello";
std::function<void(struct evhttp_request*)> response=[msg](struct evhttp_request* req){
struct evbuffer *buff=evbuffer_new();
evbuffer_add(evb, msg.c_str(), msg.size());
evhttp_send_reply(req, 200, "OK", buff);
evbuffer_free(buff);
//从funcs中删除自己, 可以自己封装类来处理,有点像csharp的ui异步线程通知类
};
funcs.push_back(response);
send(pair[0], "n", 1, 0); //让event进入_pair_callbk
});
//修改上面的evhttp_send_reply
for(auto &fun:funcs){
fun(req);
}
|