libevent之evhttp异步线程发送消息

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);
   //异步发送消息(这里只是一个测试,如果send_reply有释放req操作就会出错)
	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);
}

libevent-http模块的一小点说明

如果是文件上传: libevent-http.c 会读取Content-length的长度,到req->inputbuf中,只有数据达到这个长度后, 才会进入done中的 gencb() 功能,即自定义回调.

回调处理

在 gencb中对req增加回调函数,在其回调中对req关联的任务线程进行释放

//链接断开
static void on_evcnclose_cb(struct evhttp_connection* evcn, void* arg)
{
	LOGD("ws", "evcn close cb\n");
	struct evhttp_request* req = (struct evhttp_request*)arg;
	
}

//请求完成
static void req_on_complete_cb(struct evhttp_request* req, void* arg)
{
	LOGD("ws", "req_on_complete_cb\n");
	
}
//
void http_gencb(struct evhttp_request *request, void* arg)
{
  evhttp_request_set_on_complete_cb(req, req_on_complete_cb, NULL);
  evhttp_connection_set_closecb(evhttp_request_get_connection(req), on_evcnclose_cb, req);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值