• 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;
    }
  • 相关阅读:
    【原】list<T>排序
    [原]unity3d刀光剑影(二)
    [原]unity3D bug记录
    [原]重要工具集
    [原]IOS 后台发送邮件
    [转]IOS 崩溃日志大全(二)
    动态二维数组的建立
    struts 学习
    sizeof()与strlen()的区别
    struts配置。泪奔...
  • 原文地址:https://www.cnblogs.com/henryliublog/p/9278975.html
Copyright © 2020-2023  润新知