libevent

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, &params);

    //
    if (0 == strncmp(uri, GET_TARG_POSITION, GET_TARG_POSITION_SIZE))
    {
        CODE = decode_get_targ_position(&params, 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(&params);
    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;
}
原文地址:https://www.cnblogs.com/henryliublog/p/9278975.html