您的位置:首页 > 理论基础 > 计算机网络

libevent的http服务与libjson结合

2016-01-07 09:45 786 查看

libevent的http服务与libjson结合

最近接收了一项任务,计划在linux下的app应用程序(c++)里面添加http服务支持,因为这个app应用程序,是用libevent写的,在看到libevent有自带的http服务模块后,打算直接就拿来使用了,基本技术特点如下:

libevent+http

json支持

闲话少说,贴出代码先

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: