https://blog.csdn.net/zhuxiaoping54532/article/details/56494345
https://www.cnblogs.com/henryliublog/p/9278975.html
对于一个服务器程序,流程基本是这样的:
1. 创建socket,bind,listen,设置为非阻塞模式
2. 创建一个event_base,即
struct event_base * event_base_new(void)
3. 创建一个event,将该socket托管给event_base,指定要监听的事件类型,并绑定上相应的回调函数(及需要给它的参数)。
struct event * event_new(struct event_base *base, evutil_socket_t fd, short events, void (*cb)(evutil_socket_t, short, void *), void *arg)
4. 启用该事件
int event_add(struct event *ev, const struct timeval *tv)
5. 进入事件循环
int event_base_dispatch(struct event_base *event_base)
贴出代码先
1,main.cpp,仅贴出部分代码
if (FAILED == CHttpMgr::CreateHttpServerThread())
{
LOG_ERROR("Create Http Server Thread Failed!");
return FAILED;
}
2,HttpMgr.h
//
#ifndef _HTTPMGR_HH_
#define _HTTPMGR_HH_
#include "common.h"
#include <event2/event.h>
#include <event2/http.h>
#include <event2/buffer.h>
#include <event2/util.h>
#include <event2/keyvalq_struct.h>
#define GET_TARG_POSITION "/Target/GetPosition" //
#define GET_TARG_POSITION_SIZE 19
#define GET_TARG_BASICINFO "/Target/GetInfo" //
#define GET_TARG_BASICINFO_SIZE 15
class CHttpMgr
{
public:
//创建http服务器线程
static int CreateHttpServerThread();
//libevent循环
static void* HttpServerWorkerLibevent(void* arg);
//接收http请求
static void dump_request_cb(struct evhttp_request *req, void *arg);
//处理http GET 请求
static void handle_request_get(struct evhttp_request *req, void *arg);
//处理http POST 请求
static void handle_request_post(struct evhttp_request *req, void *arg);
//业务解码
static int decode_get_targ_position(struct evkeyvalq *params, string &str);
};
3,HttpMgr.cpp
#include "HttpMgr.h"
#include "Util.h"
#include <json/json.h>
/*****************************************************************************
函数名称 : CreateHttpServerThread
函数描述 : 创建http服务器线程
输出参数 : N/A
返回值 : int
备注 : N/A
*****************************************************************************/
int CHttpMgr::CreateHttpServerThread()
{
LOG_FUN;
struct event_base *base;
struct evhttp *http;
struct evhttp_bound_socket *handle;
unsigned short port = 8000;
base = event_base_new();
if (!base)
{
LOG_ERROR("event_base_new FAILED!");
return FAILED;
}
/* Create a new evhttp object to handle requests. */
http = evhttp_new(base);
if (!http)
{
LOG_ERROR("evhttp_new FAILED!");
return FAILED;
}
//仅接收"/Target"下的http请求
//evhttp_set_cb(http, "/Target", CHttpMgr::dump_request_cb, NULL);
//接收http任意请求
evhttp_set_gencb(http, CHttpMgr::dump_request_cb, NULL);
handle = evhttp_bind_socket_with_handle(http, "0.0.0.0", port);
if (!handle)
{
LOG_ERROR("evhttp_bind_socket_with_handle FAILED!");
return FAILED;
}
//准备结束,启动循环线程
int iRet = 0;
pthread_t tidHttpServer;
if ((iRet = pthread_create(&tidHttpServer, NULL, CHttpMgr::HttpServerWorkerLibevent, base)))
{
LOG_ERROR("Create Http Server Thread Failed! -- %d", iRet);
return FAILED;
}
return SUCCESS;
}
/*****************************************************************************
函数名称 : HttpServerWorkerLibevent
函数描述 : libevent循环
输出参数 : N/A
返回值 : void*
备注 : N/A
*****************************************************************************/
void* CHttpMgr::HttpServerWorkerLibevent(void* arg)
{
LOG_FUN;
struct event_base* pBase = static_cast<struct event_base*>(arg);
if (!pBase)
{
LOG_ERROR("Http Server thread arg FAILED!");
return NULL;
}
(void)event_base_loop(pBase, 0);
return NULL;
}
/*****************************************************************************
函数名称 : dump_request_cb
函数描述 : http请求处理函数
输出参数 : N/A
返回值 : void
备注 : N/A
*****************************************************************************/
void CHttpMgr::dump_request_cb(struct evhttp_request *req, void *arg)
{
LOG_FUN;
const char *cmdtype;
switch (evhttp_request_get_command(req))
{
case EVHTTP_REQ_GET:
{
cmdtype = "GET";
LOG_DEBUG("CMD Type GET ");
handle_request_get(req, arg);
break;
}
case EVHTTP_REQ_POST:
{
cmdtype = "POST";
LOG_DEBUG("CMD Type POST ");
handle_request_post(req, arg);
break;
}
case EVHTTP_REQ_HEAD: cmdtype = "HEAD"; LOG_DEBUG("CMD Type HEAD ");break;
case EVHTTP_REQ_PUT: cmdtype = "PUT"; LOG_DEBUG("CMD Type PUT ");break;
case EVHTTP_REQ_DELETE: cmdtype = "DELETE"; LOG_DEBUG("CMD Type DELETE ");break;
case EVHTTP_REQ_OPTIONS: cmdtype = "OPTIONS"; LOG_DEBUG("CMD Type OPTIONS "); break;
case EVHTTP_REQ_TRACE: cmdtype = "TRACE"; LOG_DEBUG("CMD Type TRACE ");break;
case EVHTTP_REQ_CONNECT: cmdtype = "CONNECT"; LOG_DEBUG("CMD Type CONNECT ");break;
case EVHTTP_REQ_PATCH: cmdtype = "PATCH"; LOG_DEBUG("CMD Type PATCH ");break;
default: cmdtype = "unknown"; LOG_DEBUG("CMD Type unknown ");break;
}
}
/*****************************************************************************
函数名称 : handle_request_get
函数描述 : Http Get请求处理函数
输出参数 : N/A
返回值 : void
备注 : N/A
*****************************************************************************/
void CHttpMgr::handle_request_get(struct evhttp_request *req, void *arg)
{
LOG_FUN;
struct evkeyvalq *headers;
struct evkeyvalq params;
struct evkeyval *header;
struct evbuffer *buf;
const char *uri;
string strOut="";//http 输出的码流
int CODE = HTTP_OK;
//获取请求的URI
uri = evhttp_request_get_uri(req);
LOG_DEBUG("Received a GET request for %s headers:", uri);
//debug 信息输出{
headers = evhttp_request_get_input_headers(req);
for (header = headers->tqh_first; header; header = header->next.tqe_next)
{
LOG_DEBUG("%s : %s", header->key, header->value);
}
//debug }
//参数查询
evhttp_parse_query(uri, ¶ms);
//
if (0 == strncmp(uri, GET_TARG_POSITION, GET_TARG_POSITION_SIZE))
{
CODE = decode_get_targ_position(¶ms, strOut);
}
else if (0 == strncmp(uri, GET_TARG_BASICINFO, GET_TARG_BASICINFO_SIZE))
{
LOG_ERROR("Expand Get Target Info Interface, havn't implemented!");
CODE = HTTP_NOTIMPLEMENTED;
strOut.append("Get Target Info not implemented");
}
else
{
LOG_ERROR("Reserved!");
CODE = HTTP_NOTIMPLEMENTED;
strOut.append("not implemented");
}
buf = evbuffer_new();
evbuffer_add_printf(buf, "%s",strOut.c_str());
//http 应答
evhttp_send_reply(req, CODE, "OK", buf);
//释放资源
evhttp_clear_headers(¶ms);
evhttp_clear_headers(headers);
evbuffer_free(buf);
}
/*****************************************************************************
函数名称 : handle_request_post
函数描述 : Http POST请求处理函数
输出参数 : N/A
返回值 : void
备注 : N/A
*****************************************************************************/
void CHttpMgr::handle_request_post(struct evhttp_request *req, void *arg)
{
LOG_FUN;
LOG_ERROR("handle_request_post Reserved!");
}
int CHttpMgr::decode_get_targ_position(struct evkeyvalq *params, string &str)
{
LOG_FUN;
//JSON格式编码
Json::Value root;
Json::Value arrayObj;
root["resultCode"] = "0";
root["TargName"] = "Test";
root["Latitude"] = "30.12345";
root["Longitude"] = "102.1323";
root["dateTime"] = 1452052317;
str = root.toStyledString();
return HTTP_OK;
}